Re: svn: /pecl/apc/trunk/ apc_cache.c apc_cache.h php_apc.c php_apc.h

From: Date: Thu, 24 Dec 2009 09:34:13 +0000
Subject: Re: svn: /pecl/apc/trunk/ apc_cache.c apc_cache.h php_apc.c php_apc.h
References: 1  Groups: php.apc.dev 
Request: Send a blank email to php-apc-dev+get-252@lists.php.net to get a copy of this message
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


« previous php.apc.dev (#252) next »