Browse Source

refactor: fall back to more simpler trick

git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1047 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
3.0
Xuefer 9 years ago
parent
commit
60acade01e
  1. 2
      mod_cacher/xc_cacher.c
  2. 2
      mod_coverager/xc_coverager.c
  3. 2
      mod_optimizer/xc_optimizer.c
  4. 115
      xcache.c
  5. 49
      xcache/xc_extension.c
  6. 4
      xcache/xc_extension.h

2
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;

2
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) /* {{{ */

2
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) /* {{{ */

115
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;

49
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;

4
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);

Loading…
Cancel
Save