Re: [PECL-CVS] svn: /pecl/apc/trunk/ apc_cache.c apc_cache.h php_apc.c php_apc.h
[email protected] (shire) Thu, 24 Dec 2009 01:34:13 -0800
| Newsgroups | php.apc.dev |
|---|---|
| Message-ID | <[email protected]> |
hrm, yeah I don't think we can get away without the lock here, simply because of the (*slot)->next/key type pointer usage. I believe the structure would allow that to be an invalid pointer if it's still in the process of being updated, inserted, removed etc.
-shire
Rasmus Lerdorf wrote:
> rasmus Wed, 23 Dec 2009 22:56:44 +0000
>
> Revision: http://svn.php.net/viewvc?view=revision&revision=292569
>
> Log:
> I think apc_exists() is useful. Here is a non-locking version.
> Still mulling over whether we can get away without the lock here.
> I think we can. Requested in bug #16981
>
> Bug: http://pecl.php.net/bugs/16981 (unknown)
>
> Changed paths:
> U pecl/apc/trunk/apc_cache.c
> U pecl/apc/trunk/apc_cache.h
> U pecl/apc/trunk/php_apc.c
> U pecl/apc/trunk/php_apc.h
>
> Modified: pecl/apc/trunk/apc_cache.c
> ===================================================================
> --- pecl/apc/trunk/apc_cache.c 2009-12-23 22:33:12 UTC (rev 292568)
> +++ pecl/apc/trunk/apc_cache.c 2009-12-23 22:56:44 UTC (rev 292569)
> @@ -635,6 +635,36 @@
> }
> /* }}} */
>
> +/* {{{ apc_cache_user_exists */
> +apc_cache_entry_t* apc_cache_user_exists(apc_cache_t* cache, char *strkey, int keylen, time_t t)
> +{
> + slot_t** slot;
> + volatile apc_cache_entry_t* value = NULL;
> +
> + if(apc_cache_busy(cache))
> + {
> + /* cache cleanup in progress */
> + return NULL;
> + }
> +
> + slot =&cache->slots[string_nhash_8(strkey, keylen) % cache->num_slots];
> +
> + while (*slot) {
> + if (!memcmp((*slot)->key.data.user.identifier, strkey, keylen)) {
> + /* Check to make sure this entry isn't expired by a hard TTL */
> + if((*slot)->value->data.user.ttl&& (time_t) ((*slot)->creation_time + (*slot)->value->data.user.ttl)< t) {
> + return NULL;
> + }
> + /* Otherwise we are fine, increase counters and return the cache entry */
> + value = (*slot)->value;
> + return (apc_cache_entry_t*)value;
> + }
> + slot =&(*slot)->next;
> + }
> + return NULL;
> +}
> +/* }}} */
> +
> /* {{{ apc_cache_user_update */
> int _apc_cache_user_update(apc_cache_t* cache, char *strkey, int keylen, apc_cache_updater_t updater, void* data TSRMLS_DC)
> {
>
> Modified: pecl/apc/trunk/apc_cache.h
> ===================================================================
> --- pecl/apc/trunk/apc_cache.h 2009-12-23 22:33:12 UTC (rev 292568)
> +++ pecl/apc/trunk/apc_cache.h 2009-12-23 22:56:44 UTC (rev 292569)
> @@ -198,6 +198,15 @@
> extern apc_cache_entry_t* apc_cache_user_find(T cache, char* strkey, int keylen, time_t t);
>
> /*
> + * apc_cache_user_exists searches for a cache entry by its hashed identifier,
> + * and returns a pointer to the entry if found, NULL otherwise. This is a
> + * quick non-locking version of apc_cache_user_find that does not modify the
> + * shared memory segment in any way.
> + *
> + */
> +extern apc_cache_entry_t* apc_cache_user_exists(T cache, char* strkey, int keylen, time_t t);
> +
> +/*
> * apc_cache_delete and apc_cache_user_delete finds an entry in the cache and deletes it.
> */
> extern int apc_cache_delete(apc_cache_t* cache, char *filename, int filename_len);
>
> Modified: pecl/apc/trunk/php_apc.c
> ===================================================================
> --- pecl/apc/trunk/php_apc.c 2009-12-23 22:33:12 UTC (rev 292568)
> +++ pecl/apc/trunk/php_apc.c 2009-12-23 22:56:44 UTC (rev 292569)
> @@ -984,7 +984,69 @@
> }
> /* }}} */
>
> +/* {{{ proto mixed apc_exists(mixed key)
> + */
> +PHP_FUNCTION(apc_exists) {
> + zval *key;
> + HashTable *hash;
> + HashPosition hpos;
> + zval **hentry;
> + char *strkey;
> + int strkey_len;
> + apc_cache_entry_t* entry;
> + zval *result;
> + zval *result_entry;
> + time_t t;
>
> + if(!APCG(enabled)) RETURN_FALSE;
> +
> + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z",&key) == FAILURE) {
> + return;
> + }
> +
> + t = apc_time();
> +
> + if(Z_TYPE_P(key) != IS_STRING&& Z_TYPE_P(key) != IS_ARRAY) {
> + convert_to_string(key);
> + }
> +
> + if(Z_TYPE_P(key) == IS_STRING) {
> + strkey = Z_STRVAL_P(key);
> + strkey_len = Z_STRLEN_P(key);
> + if(!strkey_len) RETURN_FALSE;
> + entry = apc_cache_user_exists(apc_user_cache, strkey, strkey_len + 1, t);
> + if(entry) {
> + RETURN_TRUE;
> + }
> + } else if(Z_TYPE_P(key) == IS_ARRAY) {
> + hash = Z_ARRVAL_P(key);
> + MAKE_STD_ZVAL(result);
> + array_init(result);
> + zend_hash_internal_pointer_reset_ex(hash,&hpos);
> + while(zend_hash_get_current_data_ex(hash, (void**)&hentry,&hpos) == SUCCESS) {
> + if(Z_TYPE_PP(hentry) != IS_STRING) {
> + apc_wprint("apc_exists() expects a string or array of strings.");
> + goto done;
> + }
> + entry = apc_cache_user_exists(apc_user_cache, Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) + 1, t);
> + if(entry) {
> + MAKE_STD_ZVAL(result_entry);
> + ZVAL_BOOL(result_entry, 1);
> + zend_hash_add(Z_ARRVAL_P(result), Z_STRVAL_PP(hentry), Z_STRLEN_PP(hentry) +1,&result_entry, sizeof(zval*), NULL);
> + } /* don't set values we didn't find */
> + zend_hash_move_forward_ex(hash,&hpos);
> + }
> + RETVAL_ZVAL(result, 0, 1);
> + } else {
> + apc_wprint("apc_exists() expects a string or array of strings.");
> + }
> +
> +done:
> + RETURN_FALSE;
> +}
> +/* }}} */
> +
> +
> /* {{{ proto mixed apc_delete(mixed keys)
> */
> PHP_FUNCTION(apc_delete) {
> @@ -1680,6 +1742,11 @@
> ZEND_ARG_INFO(0, context)
> ZEND_ARG_INFO(0, flags)
> ZEND_END_ARG_INFO()
> +
> +PHP_APC_ARGINFO
> +ZEND_BEGIN_ARG_INFO(arginfo_apc_exists, 0)
> + ZEND_ARG_INFO(0, keys)
> +ZEND_END_ARG_INFO()
> /* }}} */
>
> /* {{{ apc_functions[] */
> @@ -1702,6 +1769,7 @@
> PHP_FE(apc_bin_load, arginfo_apc_bin_load)
> PHP_FE(apc_bin_dumpfile, arginfo_apc_bin_dumpfile)
> PHP_FE(apc_bin_loadfile, arginfo_apc_bin_loadfile)
> + PHP_FE(apc_exists, arginfo_apc_exists)
> {NULL, NULL, NULL}
> };
> /* }}} */
>
> Modified: pecl/apc/trunk/php_apc.h
> ===================================================================
> --- pecl/apc/trunk/php_apc.h 2009-12-23 22:33:12 UTC (rev 292568)
> +++ pecl/apc/trunk/php_apc.h 2009-12-23 22:56:44 UTC (rev 292569)
> @@ -35,7 +35,7 @@
> #include "apc_php.h"
> #include "apc_globals.h"
>
> -#define PHP_APC_VERSION "3.1.3p1"
> +#define PHP_APC_VERSION "3.1.4-dev"
>
> extern zend_module_entry apc_module_entry;
> #define apc_module_ptr&apc_module_entry
>
>