/* {{{ php_ini_register_extensions */ void php_ini_register_extensions(void) { zend_llist_apply(&extension_lists.engine, php_load_zend_extension_cb); zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb); zend_llist_destroy(&extension_lists.engine); zend_llist_destroy(&extension_lists.functions); }
void php_ini_delayed_modules_startup(void) { zend_llist_apply(&extension_lists.engine, php_load_zend_extension_cb); zend_llist_apply(&extension_lists.functions, php_load_function_extension_cb); zend_llist_destroy(&extension_lists.engine); zend_llist_destroy(&extension_lists.functions); }
void init_executor(void) /* {{{ */ { zend_init_fpu(); ZVAL_NULL(&EG(uninitialized_zval)); ZVAL_NULL(&EG(error_zval)); /* destroys stack frame, therefore makes core dumps worthless */ #if 0&&ZEND_DEBUG original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv); #endif EG(symtable_cache_ptr) = EG(symtable_cache) - 1; EG(symtable_cache_limit) = EG(symtable_cache) + SYMTABLE_CACHE_SIZE - 1; EG(no_extensions) = 0; EG(function_table) = CG(function_table); EG(class_table) = CG(class_table); EG(in_autoload) = NULL; EG(autoload_func) = NULL; EG(error_handling) = EH_NORMAL; zend_vm_stack_init(); zend_hash_init(&EG(symbol_table), 64, NULL, ZVAL_PTR_DTOR, 0); EG(valid_symbol_table) = 1; zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator); zend_hash_init(&EG(included_files), 8, NULL, NULL, 0); EG(ticks_count) = 0; ZVAL_UNDEF(&EG(user_error_handler)); EG(current_execute_data) = NULL; zend_stack_init(&EG(user_error_handlers_error_reporting), sizeof(int)); zend_stack_init(&EG(user_error_handlers), sizeof(zval)); zend_stack_init(&EG(user_exception_handlers), sizeof(zval)); zend_objects_store_init(&EG(objects_store), 1024); EG(full_tables_cleanup) = 0; #ifdef ZEND_WIN32 EG(timed_out) = 0; #endif EG(exception) = NULL; EG(prev_exception) = NULL; EG(scope) = NULL; EG(ht_iterators_count) = sizeof(EG(ht_iterators_slots)) / sizeof(HashTableIterator); EG(ht_iterators_used) = 0; EG(ht_iterators) = EG(ht_iterators_slots); memset(EG(ht_iterators), 0, sizeof(EG(ht_iterators_slots))); EG(active) = 1; }
static void print_extensions(void) /* {{{ */ { zend_llist sorted_exts; zend_llist_copy(&sorted_exts, &zend_extensions); sorted_exts.dtor = NULL; zend_llist_sort(&sorted_exts, extension_name_cmp); zend_llist_apply(&sorted_exts, (llist_apply_func_t) print_extension_info); zend_llist_destroy(&sorted_exts); }
void shutdown_executor(void) /* {{{ */ { zend_string *key; zval *zv; #if ZEND_DEBUG zend_bool fast_shutdown = 0; #else zend_bool fast_shutdown = is_zend_mm() && !EG(full_tables_cleanup); #endif zend_try { zend_llist_destroy(&CG(open_files)); } zend_end_try(); zend_try { zend_close_rsrc_list(&EG(regular_list)); } zend_end_try(); zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown); /* All resources and objects are destroyed. */ /* No PHP callback functions may be called after this point. */ EG(active) = 0; zend_try { zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator); } zend_end_try(); if (fast_shutdown) { /* Fast Request Shutdown * ===================== * Zend Memory Manager frees memory by its own. We don't have to free * each allocated block separately. */ ZEND_HASH_REVERSE_FOREACH_VAL(EG(zend_constants), zv) { zend_constant *c = Z_PTR_P(zv); if (c->flags & CONST_PERSISTENT) { break; } } ZEND_HASH_FOREACH_END_DEL(); ZEND_HASH_REVERSE_FOREACH_VAL(EG(function_table), zv) { zend_function *func = Z_PTR_P(zv); if (func->type == ZEND_INTERNAL_FUNCTION) { break; } } ZEND_HASH_FOREACH_END_DEL();
void shutdown_executor(void) /* {{{ */ { zend_function *func; zend_class_entry *ce; zend_try { /* Removed because this can not be safely done, e.g. in this situation: Object 1 creates object 2 Object 3 holds reference to object 2. Now when 1 and 2 are destroyed, 3 can still access 2 in its destructor, with very problematic results */ /* zend_objects_store_call_destructors(&EG(objects_store)); */ /* Moved after symbol table cleaners, because some of the cleaners can call destructors, which would use EG(symtable_cache_ptr) and thus leave leaks */ /* while (EG(symtable_cache_ptr)>=EG(symtable_cache)) { zend_hash_destroy(*EG(symtable_cache_ptr)); efree(*EG(symtable_cache_ptr)); EG(symtable_cache_ptr)--; } */ zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator); if (CG(unclean_shutdown)) { EG(symbol_table).ht.pDestructor = zend_unclean_zval_ptr_dtor; } zend_hash_graceful_reverse_destroy(&EG(symbol_table).ht); } zend_end_try(); EG(valid_symbol_table) = 0; zend_try { zval *zeh; /* remove error handlers before destroying classes and functions, * so that if handler used some class, crash would not happen */ if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) { zeh = &EG(user_error_handler); zval_ptr_dtor(zeh); ZVAL_UNDEF(&EG(user_error_handler)); } if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) { zeh = &EG(user_exception_handler); zval_ptr_dtor(zeh); ZVAL_UNDEF(&EG(user_exception_handler)); } zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1); zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 1); zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 1); } zend_end_try(); zend_try { /* Cleanup static data for functions and arrays. * We need a separate cleanup stage because of the following problem: * Suppose we destroy class X, which destroys the class's function table, * and in the function table we have function foo() that has static $bar. * Now if an object of class X is assigned to $bar, its destructor will be * called and will fail since X's function table is in mid-destruction. * So we want first of all to clean up all data and then move to tables destruction. * Note that only run-time accessed data need to be cleaned up, pre-defined data can * not contain objects and thus are not probelmatic */ if (EG(full_tables_cleanup)) { ZEND_HASH_FOREACH_PTR(EG(function_table), func) { if (func->type == ZEND_USER_FUNCTION) { zend_cleanup_op_array_data((zend_op_array *) func); } } ZEND_HASH_FOREACH_END(); ZEND_HASH_REVERSE_FOREACH_PTR(EG(class_table), ce) { if (ce->type == ZEND_USER_CLASS) { zend_cleanup_user_class_data(ce); } else { zend_cleanup_internal_class_data(ce); } } ZEND_HASH_FOREACH_END(); } else { ZEND_HASH_REVERSE_FOREACH_PTR(EG(function_table), func) { if (func->type != ZEND_USER_FUNCTION) { break; } zend_cleanup_op_array_data((zend_op_array *) func); } ZEND_HASH_FOREACH_END(); ZEND_HASH_REVERSE_FOREACH_PTR(EG(class_table), ce) { if (ce->type != ZEND_USER_CLASS) { break; } zend_cleanup_user_class_data(ce); } ZEND_HASH_FOREACH_END(); zend_cleanup_internal_classes(); } } zend_end_try();
void zend_shutdown_extensions(void) { zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_shutdown); zend_llist_destroy(&zend_extensions); }