From 60acade01e861e92252d01517a5b6b47b1d88124 Mon Sep 17 00:00:00 2001 From: Xuefer Date: Wed, 25 Jul 2012 10:56:27 +0000 Subject: [PATCH] refactor: fall back to more simpler trick git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1047 c26eb9a1-5813-0410-bd6c-c2e55f420ca7 --- mod_cacher/xc_cacher.c | 2 +- mod_coverager/xc_coverager.c | 2 +- mod_optimizer/xc_optimizer.c | 2 +- xcache.c | 115 +++++++++++++++++++++-------------- xcache/xc_extension.c | 49 +++------------ xcache/xc_extension.h | 4 +- 6 files changed, 82 insertions(+), 92 deletions(-) diff --git a/mod_cacher/xc_cacher.c b/mod_cacher/xc_cacher.c index 81f70d8..44035be 100644 --- a/mod_cacher/xc_cacher.c +++ b/mod_cacher/xc_cacher.c @@ -3253,7 +3253,7 @@ static PHP_MINIT_FUNCTION(xcache_cacher) /* {{{ */ REGISTER_INI_ENTRIES(); xc_sandbox_module_init(module_number TSRMLS_CC); - return xcache_zend_extension_prepend(&xc_cacher_zend_extension_entry); + return xcache_zend_extension_add(&xc_cacher_zend_extension_entry, 0); err_init: return FAILURE; diff --git a/mod_coverager/xc_coverager.c b/mod_coverager/xc_coverager.c index 1f859cb..59c6ab8 100644 --- a/mod_coverager/xc_coverager.c +++ b/mod_coverager/xc_coverager.c @@ -670,7 +670,7 @@ static PHP_MINIT_FUNCTION(xcache_coverager) /* {{{ */ } } - return xcache_zend_extension_prepend(&xc_coverager_zend_extension_entry); + return xcache_zend_extension_add(&xc_coverager_zend_extension_entry, 0); } /* }}} */ static PHP_MSHUTDOWN_FUNCTION(xcache_coverager) /* {{{ */ diff --git a/mod_optimizer/xc_optimizer.c b/mod_optimizer/xc_optimizer.c index 7467951..c4543a3 100644 --- a/mod_optimizer/xc_optimizer.c +++ b/mod_optimizer/xc_optimizer.c @@ -666,7 +666,7 @@ static PHP_MINFO_FUNCTION(xcache_optimizer) /* {{{ */ static PHP_MINIT_FUNCTION(xcache_optimizer) /* {{{ */ { REGISTER_INI_ENTRIES(); - return xcache_zend_extension_prepend(&xc_optimizer_zend_extension_entry); + return xcache_zend_extension_add(&xc_optimizer_zend_extension_entry, 0); } /* }}} */ static PHP_MSHUTDOWN_FUNCTION(xcache_optimizer) /* {{{ */ diff --git a/xcache.c b/xcache.c index c855b4a..58961eb 100644 --- a/xcache.c +++ b/xcache.c @@ -542,55 +542,81 @@ static void xcache_signal_handler(int sig) /* {{{ */ /* }}} */ #endif -static startup_func_t xc_last_ext_old_startup; -static xc_stack_t xc_llist_zend_extensions; /* (zend_extension *) */ -static int xc_zend_startup_last_hook(zend_extension *extension) /* {{{ */ +/* {{{ incompatible zend extensions handling */ +typedef struct { + const char *name; + startup_func_t old_startup; +} xc_incompatible_zend_extension_info_t; +static xc_incompatible_zend_extension_info_t xc_incompatible_zend_extensions[] = { + { "Zend Optimizer", NULL } +}; + +static xc_incompatible_zend_extension_info_t *xc_get_incompatible_zend_extension_info(const char *name) { - zend_extension *ext = zend_get_extension(XCACHE_NAME); - if (ext) { - zend_error(E_WARNING, "Module '" XCACHE_NAME "' already loaded"); - } - /* restore */ - extension->startup = xc_last_ext_old_startup; - extension->startup = xc_last_ext_old_startup; - xc_last_ext_old_startup = NULL; - if (extension->startup) { - if (extension->startup(extension) != SUCCESS) { - return FAILURE; + size_t i; + + for (i = 0; i < sizeof(xc_incompatible_zend_extensions) / sizeof(xc_incompatible_zend_extensions[0]); ++i) { + xc_incompatible_zend_extension_info_t *incompatible_zend_extension_info = &xc_incompatible_zend_extensions[i]; + if (strcmp(incompatible_zend_extension_info->name, name) == 0) { + return incompatible_zend_extension_info; } } - assert(xc_stack_count(&xc_llist_zend_extensions)); - while (xc_stack_count(&xc_llist_zend_extensions)) { - zend_llist_element *p = (zend_llist_element *) xc_stack_pop(&xc_llist_zend_extensions); - xcache_llist_prepend(&zend_extensions, p); + return NULL; +} +/* }}} */ +static int xc_incompatible_zend_extension_startup_hook(zend_extension *extension) /* {{{ */ +{ + xc_incompatible_zend_extension_info_t *incompatible_zend_extension_info = xc_get_incompatible_zend_extension_info(extension->name); + int status; + zend_bool catched = 0; + zend_llist old_zend_extensions = zend_extensions; + TSRMLS_FETCH(); + + /* hide all extensions from it */ + zend_extensions.head = NULL; + zend_extensions.count = 0; + + /* restore */ + extension->startup = incompatible_zend_extension_info->old_startup; + incompatible_zend_extension_info->old_startup = NULL; + assert(extension->startup); + + zend_try { + status = extension->startup(extension); + } zend_catch { + catched = 1; + } zend_end_try(); + + zend_extensions = old_zend_extensions; + if (catched) { + zend_bailout(); } - xc_stack_destroy(&xc_llist_zend_extensions); - return SUCCESS; + return status; } /* }}} */ static int xc_zend_startup(zend_extension *extension) /* {{{ */ { + zend_llist_position lpos; + zend_extension *ext; + + ext = (zend_extension *) zend_extensions.head->data; + if (strcmp(ext->name, XCACHE_NAME) != 0) { + zend_error(E_WARNING, "XCache failed to load itself as the before \"%s\". compatibility downgraded", ext->name); + } + old_compile_file = zend_compile_file; zend_compile_file = xc_check_initial_compile_file; - if (1 || xcache_zend_extension_count_by_prefix(&zend_extensions, XCACHE_NAME) != zend_llist_count(&zend_extensions)) { - zend_llist_position lpos; - zend_extension *ext = (zend_extension *) zend_extensions.head->data; - assert(ext); - - if (strcmp(ext->name, XCACHE_NAME) != 0) { - zend_error(E_WARNING, "XCache failed to load itself as the before \"%s\". compatibility downgraded", ext->name); + for (ext = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &lpos); + ext; + ext = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &lpos)) { + xc_incompatible_zend_extension_info_t *incompatible_zend_extension_info = xc_get_incompatible_zend_extension_info(extension->name); + if (incompatible_zend_extension_info) { + assert(!incompatible_zend_extension_info->old_startup); + incompatible_zend_extension_info->old_startup = ext->startup; + ext->startup = xc_incompatible_zend_extension_startup_hook; } - - /* hide XCache modules */ - xc_stack_init(&xc_llist_zend_extensions); - xcache_zend_extension_unlink_by_prefix(&xc_llist_zend_extensions, &zend_extensions, XCACHE_NAME); - - ext = (zend_extension *) zend_llist_get_last_ex(&zend_extensions, &lpos); - assert(ext); - xc_last_ext_old_startup = ext->startup; - ext->startup = xc_zend_startup_last_hook; } return SUCCESS; } @@ -656,21 +682,20 @@ static PHP_MINIT_FUNCTION(xcache) /* {{{ */ xc_init_constant(module_number TSRMLS_CC); xc_shm_init_modules(); - /* ZendExtension is registered in reverse order for prepend by XCache */ + /* must be the first */ + xcache_zend_extension_add(&xc_zend_extension_entry, 1); +#ifdef HAVE_XCACHE_OPTIMIZER + xc_optimizer_startup_module(); +#endif +#ifdef HAVE_XCACHE_CACHER + xc_cacher_startup_module(); +#endif #ifdef HAVE_XCACHE_COVERAGER xc_coverager_startup_module(); #endif #ifdef HAVE_XCACHE_DISASSEMBLER xc_disassembler_startup_module(); #endif -#ifdef HAVE_XCACHE_CACHER - xc_cacher_startup_module(); -#endif -#ifdef HAVE_XCACHE_OPTIMIZER - xc_optimizer_startup_module(); -#endif - /* must be the first */ - xcache_zend_extension_prepend(&xc_zend_extension_entry); return SUCCESS; diff --git a/xcache/xc_extension.c b/xcache/xc_extension.c index daf4d6d..f2f44ed 100644 --- a/xcache/xc_extension.c +++ b/xcache/xc_extension.c @@ -4,7 +4,7 @@ #include "util/xc_trace.h" -int xcache_zend_extension_prepend(zend_extension *new_extension) /* {{{ */ +int xcache_zend_extension_add(zend_extension *new_extension, zend_bool prepend) /* {{{ */ { zend_extension extension; @@ -13,8 +13,13 @@ int xcache_zend_extension_prepend(zend_extension *new_extension) /* {{{ */ zend_extension_dispatch_message(ZEND_EXTMSG_NEW_EXTENSION, &extension); - zend_llist_prepend_element(&zend_extensions, &extension); - TRACE("%s", "prepended"); + if (prepend) { + zend_llist_prepend_element(&zend_extensions, &extension); + } + else { + zend_llist_add_element(&zend_extensions, &extension); + } + TRACE("%s", "registered"); return SUCCESS; } /* }}} */ @@ -50,44 +55,6 @@ int xcache_zend_extension_remove(zend_extension *extension) /* {{{ */ } /* }}} */ -int xcache_zend_extension_count_by_prefix(zend_llist *l, const char *extension_name_prefix) /* {{{ */ -{ - zend_llist_element *element; - size_t n = strlen(extension_name_prefix); - int count = 0; - - for (element = zend_extensions.head; element; element = element->next) { - zend_extension *extension = (zend_extension *) element->data; - - if (strncmp(extension->name, extension_name_prefix, n) == 0) { - ++count; - } - } - return count; -} -/* }}} */ -void xcache_zend_extension_unlink_by_prefix(xc_stack_t *linked, zend_llist *l, const char *extension_name_prefix) /* {{{ */ -{ - size_t n = strlen(extension_name_prefix); - zend_llist_element *unlinked = NULL; - zend_llist_element *element, *next; - - for (element = zend_extensions.head; element; element = next) { - zend_extension *extension = (zend_extension *) element->data; - next = element->next; - - if (strncmp(extension->name, extension_name_prefix, n) == 0) { - xcache_llist_unlink(l, element); - xc_stack_push(linked, element); - } - } - - for (element = zend_extensions.head; element; element = next) { - zend_extension *extension = (zend_extension *) element->data; - next = element->next; - } -} -/* }}} */ void xcache_llist_prepend(zend_llist *l, zend_llist_element *element) /* {{{ */ { element->next = l->head; diff --git a/xcache/xc_extension.h b/xcache/xc_extension.h index 7a18909..ec152e0 100644 --- a/xcache/xc_extension.h +++ b/xcache/xc_extension.h @@ -7,10 +7,8 @@ #include "util/xc_stack.h" #include "zend_extensions.h" -int xcache_zend_extension_prepend(zend_extension *new_extension); +int xcache_zend_extension_add(zend_extension *new_extension, zend_bool prepend); int xcache_zend_extension_remove(zend_extension *extension); -int xcache_zend_extension_count_by_prefix(zend_llist *l, const char *extension_name_prefix); -void xcache_zend_extension_unlink_by_prefix(xc_stack_t *unlinked, zend_llist *l, const char *extension_name_prefix); void xcache_llist_prepend(zend_llist *l, zend_llist_element *element); void xcache_llist_unlink(zend_llist *l, zend_llist_element *element);