]> granicus.if.org Git - php/commitdiff
Keep realpath and PCRE caches in consistency with opcache SHM.
authorDmitry Stogov <dmitry@zend.com>
Tue, 21 Apr 2015 23:29:06 +0000 (02:29 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 21 Apr 2015 23:29:06 +0000 (02:29 +0300)
Zend/zend_hash.c
Zend/zend_hash.h
ext/opcache/ZendAccelerator.c
ext/opcache/ZendAccelerator.h
ext/pcre/php_pcre.c
ext/pcre/php_pcre.h

index fcb51f6a2f01574591b0aa83c7a1634f50a7370f..5aa8620683d44a7ab0c5fbf726127419c374b7f4 100644 (file)
@@ -924,6 +924,13 @@ static zend_always_inline void _zend_hash_del_el(HashTable *ht, uint32_t idx, Bu
        _zend_hash_del_el_ex(ht, idx, p, prev);
 }
 
+ZEND_API void ZEND_FASTCALL zend_hash_del_bucket(HashTable *ht, Bucket *p)
+{
+       IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
+       _zend_hash_del_el(ht, HT_IDX_TO_HASH(p - ht->arData), p);
+}
+
 ZEND_API int ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key)
 {
        zend_ulong h;
index 9dec40d57a3eddcdc53b83803d05869144d9a7a1..7ef9242ad2883451f0f7173197f255d991489e76 100644 (file)
@@ -145,6 +145,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_del_ind(HashTable *ht, zend_string *key);
 ZEND_API int ZEND_FASTCALL zend_hash_str_del(HashTable *ht, const char *key, size_t len);
 ZEND_API int ZEND_FASTCALL zend_hash_str_del_ind(HashTable *ht, const char *key, size_t len);
 ZEND_API int ZEND_FASTCALL zend_hash_index_del(HashTable *ht, zend_ulong h);
+ZEND_API void ZEND_FASTCALL zend_hash_del_bucket(HashTable *ht, Bucket *p);
 
 /* Data retreival */
 ZEND_API zval* ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key);
index 8259cfa9af3d8e487cb6bb45da265383a6c0b4b2..ede6efd94c86756ba16b01bf846a523324bad116 100644 (file)
@@ -39,6 +39,7 @@
 #include "zend_virtual_cwd.h"
 #include "zend_accelerator_util_funcs.h"
 #include "zend_accelerator_hash.h"
+#include "ext/pcre/php_pcre.h"
 
 #ifndef ZEND_WIN32
 #include  <netdb.h>
@@ -1799,8 +1800,26 @@ static void zend_reset_cache_vars(void)
        ZCSG(force_restart_time) = 0;
 }
 
+#ifndef ZTS
+static void accel_reset_pcre_cache(void)
+{
+       Bucket *p;
+
+       ZEND_HASH_FOREACH_BUCKET(&PCRE_G(pcre_cache), p) {
+               /* Remove PCRE cache entries with inconsistent keys */
+               if (IS_ACCEL_INTERNED(p->key)) {
+                       p->key = NULL;
+                       zend_hash_del_bucket(&PCRE_G(pcre_cache), p);
+               }
+       } ZEND_HASH_FOREACH_END();
+}
+#endif
+
 static void accel_activate(void)
 {
+#ifndef ZTS
+       zend_bool reset_pcre = 0;
+#endif
 
        if (!ZCG(enabled) || !accel_startup_ok) {
                return;
@@ -1860,9 +1879,17 @@ static void accel_activate(void)
 
                                zend_shared_alloc_restore_state();
                                ZCSG(accelerator_enabled) = ZCSG(cache_status_before_restart);
-                               ZCSG(last_restart_time) = ZCG(request_time);
+                               if (ZCSG(last_restart_time) < ZCG(request_time)) {
+                                       ZCSG(last_restart_time) = ZCG(request_time);
+                               } else {
+                                       ZCSG(last_restart_time)++;
+                               }
                                accel_restart_leave();
                        }
+#ifndef ZTS
+               } else {
+                       reset_pcre = 1;
+#endif
                }
                zend_shared_alloc_unlock();
        }
@@ -1877,6 +1904,20 @@ static void accel_activate(void)
        ZCG(cwd_check) = 1;
 
        SHM_PROTECT();
+
+       if (ZCSG(last_restart_time) != ZCG(last_restart_time)) {
+               /* SHM was reinitialized. */
+               ZCG(last_restart_time) = ZCSG(last_restart_time);
+
+               /* Reset in-process realpath cache */
+               realpath_cache_clean();
+
+#ifndef ZTS
+               accel_reset_pcre_cache();
+       } else if (reset_pcre) {
+               accel_reset_pcre_cache();
+#endif
+       }
 }
 
 #if !ZEND_DEBUG
@@ -2316,6 +2357,9 @@ static int accel_startup(zend_extension *extension)
                        break;
        }
 
+       /* remeber the last restart time in the process memory */
+       ZCG(last_restart_time) = ZCSG(last_restart_time);
+
        /* from this point further, shared memory is supposed to be OK */
 
        /* Init auto-global strings */
@@ -2400,6 +2444,8 @@ void accel_shutdown(void)
                zend_hash_clean(CG(function_table));
                zend_hash_clean(CG(class_table));
                zend_hash_clean(EG(zend_constants));
+
+               accel_reset_pcre_cache();
 #endif
        }
 
index aa385626874ca9ae48b7e9c38fcc18c9930aa93d..a41d0a94d0bfab5c7aa98994d7ef4184870ec1f1 100644 (file)
@@ -237,6 +237,7 @@ typedef struct _zend_accel_globals {
        int                     cwd_check;
        int                     auto_globals_mask;
        time_t                  request_time;
+       time_t                  last_restart_time; /* used to synchronize SHM and in-process caches */
        /* preallocated shared-memory block to save current script */
        void                   *mem;
        void                   *arena_mem;
index 4c29905d2fa546bb14b664d7a0e08d77c329f500..1f013408fc1ee260cb5d3557096a0554dc08a64c 100644 (file)
@@ -54,7 +54,7 @@ enum {
 };
 
 
-ZEND_DECLARE_MODULE_GLOBALS(pcre)
+PHPAPI ZEND_DECLARE_MODULE_GLOBALS(pcre)
 
 
 static void pcre_handle_exec_error(int pcre_code) /* {{{ */
@@ -482,7 +482,14 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex)
         * as hash keys especually for this table.
         * See bug #63180
         */
-       pce = zend_hash_str_update_mem(&PCRE_G(pcre_cache), regex->val, regex->len, &new_entry, sizeof(pcre_cache_entry));
+       if (!IS_INTERNED(regex) || !(GC_FLAGS(regex) & IS_STR_PERMANENT)) {
+               zend_string *str = zend_string_init(regex->val, regex->len, 1);
+               GC_REFCOUNT(str) = 0; /* will be incremented by zend_hash_update_mem() */
+               str->h = regex->h;
+               regex = str;
+       }
+
+       pce = zend_hash_update_mem(&PCRE_G(pcre_cache), regex, &new_entry, sizeof(pcre_cache_entry));
 
        return pce;
 }
index 98882cce4e1ce012c48e9af580b54ac601983024..fb155c467e4f5853c041496a2ab6a74a74ff0e78 100644 (file)
@@ -81,6 +81,8 @@ ZEND_BEGIN_MODULE_GLOBALS(pcre)
        int  error_code;
 ZEND_END_MODULE_GLOBALS(pcre)
 
+PHPAPI ZEND_EXTERN_MODULE_GLOBALS(pcre);
+
 #ifdef ZTS
 # define PCRE_G(v) ZEND_TSRMG(pcre_globals_id, zend_pcre_globals *, v)
 #else