summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-04-22 02:29:06 +0300
committerDmitry Stogov <dmitry@zend.com>2015-04-22 02:29:06 +0300
commit770cb1da71656fa0dce7dfab26e5e88cb557b639 (patch)
tree730e919e37a87fba9302839613fba6bc2ceb9bca
parentc9da004a1884f54ad69b8b66e585f1ba451e84ee (diff)
downloadphp-git-770cb1da71656fa0dce7dfab26e5e88cb557b639.tar.gz
Keep realpath and PCRE caches in consistency with opcache SHM.
-rw-r--r--Zend/zend_hash.c7
-rw-r--r--Zend/zend_hash.h1
-rw-r--r--ext/opcache/ZendAccelerator.c48
-rw-r--r--ext/opcache/ZendAccelerator.h1
-rw-r--r--ext/pcre/php_pcre.c11
-rw-r--r--ext/pcre/php_pcre.h2
6 files changed, 67 insertions, 3 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index fcb51f6a2f..5aa8620683 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -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;
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
index 9dec40d57a..7ef9242ad2 100644
--- a/Zend/zend_hash.h
+++ b/Zend/zend_hash.h
@@ -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);
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 8259cfa9af..ede6efd94c 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -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
}
diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h
index aa38562687..a41d0a94d0 100644
--- a/ext/opcache/ZendAccelerator.h
+++ b/ext/opcache/ZendAccelerator.h
@@ -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;
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index 4c29905d2f..1f013408fc 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -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;
}
diff --git a/ext/pcre/php_pcre.h b/ext/pcre/php_pcre.h
index 98882cce4e..fb155c467e 100644
--- a/ext/pcre/php_pcre.h
+++ b/ext/pcre/php_pcre.h
@@ -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