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