mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Implement a more granular shutdown mechanism for the executor -
prevent corruption of constants and missing destructions of resources
This commit is contained in:
parent
13ac04b8e5
commit
8084d27885
3 changed files with 62 additions and 34 deletions
|
@ -536,9 +536,8 @@ void zend_deactivate(CLS_D ELS_DC)
|
||||||
if (setjmp(EG(bailout))==0) {
|
if (setjmp(EG(bailout))==0) {
|
||||||
shutdown_scanner(CLS_C);
|
shutdown_scanner(CLS_C);
|
||||||
}
|
}
|
||||||
if (setjmp(EG(bailout))==0) {
|
/* shutdown_executor() takes care of its own bailout handling */
|
||||||
shutdown_executor(ELS_C);
|
shutdown_executor(ELS_C);
|
||||||
}
|
|
||||||
if (setjmp(EG(bailout))==0) {
|
if (setjmp(EG(bailout))==0) {
|
||||||
shutdown_compiler(CLS_C);
|
shutdown_compiler(CLS_C);
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,49 +152,53 @@ void init_executor(CLS_D ELS_DC)
|
||||||
|
|
||||||
void shutdown_executor(ELS_D)
|
void shutdown_executor(ELS_D)
|
||||||
{
|
{
|
||||||
zend_ptr_stack_destroy(&EG(arg_types_stack));
|
if (setjmp(EG(bailout))==0) {
|
||||||
|
zend_ptr_stack_destroy(&EG(arg_types_stack));
|
||||||
|
|
||||||
while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
|
while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
|
||||||
zend_hash_destroy(*EG(symtable_cache_ptr));
|
zend_hash_destroy(*EG(symtable_cache_ptr));
|
||||||
efree(*EG(symtable_cache_ptr));
|
efree(*EG(symtable_cache_ptr));
|
||||||
EG(symtable_cache_ptr)--;
|
EG(symtable_cache_ptr)--;
|
||||||
}
|
|
||||||
zend_llist_apply(&zend_extensions, (void (*)(void *)) zend_extension_deactivator);
|
|
||||||
|
|
||||||
zend_hash_destroy(&EG(symbol_table));
|
|
||||||
|
|
||||||
while (EG(garbage_ptr)--) {
|
|
||||||
if (EG(garbage)[EG(garbage_ptr)]->refcount==1) {
|
|
||||||
zval_ptr_dtor(&EG(garbage)[EG(garbage_ptr)]);
|
|
||||||
}
|
}
|
||||||
|
zend_llist_apply(&zend_extensions, (void (*)(void *)) zend_extension_deactivator);
|
||||||
|
|
||||||
|
zend_hash_destroy(&EG(symbol_table));
|
||||||
|
|
||||||
|
while (EG(garbage_ptr)--) {
|
||||||
|
if (EG(garbage)[EG(garbage_ptr)]->refcount==1) {
|
||||||
|
zval_ptr_dtor(&EG(garbage)[EG(garbage_ptr)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zend_ptr_stack_destroy(&EG(argument_stack));
|
||||||
|
|
||||||
|
/* Destroy all op arrays */
|
||||||
|
zend_hash_apply(EG(function_table), (int (*)(void *)) is_not_internal_function);
|
||||||
|
zend_hash_apply(EG(class_table), (int (*)(void *)) is_not_internal_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
zend_ptr_stack_destroy(&EG(argument_stack));
|
|
||||||
|
|
||||||
/* Destroy all op arrays */
|
|
||||||
zend_hash_apply(EG(function_table), (int (*)(void *)) is_not_internal_function);
|
|
||||||
zend_hash_apply(EG(class_table), (int (*)(void *)) is_not_internal_class);
|
|
||||||
|
|
||||||
zend_destroy_rsrc_list(ELS_C); /* must be destroyed after the main symbol table and
|
zend_destroy_rsrc_list(ELS_C); /* must be destroyed after the main symbol table and
|
||||||
* op arrays are destroyed.
|
* op arrays are destroyed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
clean_non_persistent_constants();
|
if (setjmp(EG(bailout))==0) {
|
||||||
|
clean_non_persistent_constants();
|
||||||
#if ZEND_DEBUG
|
#if ZEND_DEBUG
|
||||||
signal(SIGSEGV, original_sigsegv_handler);
|
signal(SIGSEGV, original_sigsegv_handler);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
zend_hash_destroy(&EG(included_files));
|
zend_hash_destroy(&EG(included_files));
|
||||||
|
|
||||||
if (EG(user_error_handler)) {
|
if (EG(user_error_handler)) {
|
||||||
zval_dtor(EG(user_error_handler));
|
zval_dtor(EG(user_error_handler));
|
||||||
FREE_ZVAL(EG(user_error_handler));
|
FREE_ZVAL(EG(user_error_handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
zend_ptr_stack_clean(&EG(user_error_handlers), ZVAL_DESTRUCTOR, 1);
|
||||||
|
zend_ptr_stack_destroy(&EG(user_error_handlers));
|
||||||
|
|
||||||
|
EG(error_reporting) = EG(orig_error_reporting);
|
||||||
}
|
}
|
||||||
|
|
||||||
zend_ptr_stack_clean(&EG(user_error_handlers), ZVAL_DESTRUCTOR, 1);
|
|
||||||
zend_ptr_stack_destroy(&EG(user_error_handlers));
|
|
||||||
|
|
||||||
EG(error_reporting) = EG(orig_error_reporting);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -231,10 +231,35 @@ int zend_init_rsrc_plist(ELS_D)
|
||||||
|
|
||||||
void zend_destroy_rsrc_list(ELS_D)
|
void zend_destroy_rsrc_list(ELS_D)
|
||||||
{
|
{
|
||||||
zend_hash_reverse_destroy(&EG(regular_list));
|
Bucket *p, *q;
|
||||||
|
HashTable *ht = &EG(regular_list);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
p = ht->pListTail;
|
||||||
|
if (!p) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
q = p->pListLast;
|
||||||
|
if (q) {
|
||||||
|
q->pListNext = NULL;
|
||||||
|
}
|
||||||
|
ht->pListTail = q;
|
||||||
|
|
||||||
|
if (ht->pDestructor) {
|
||||||
|
if (setjmp(EG(bailout))==0) {
|
||||||
|
ht->pDestructor(p->pData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!p->pDataPtr && p->pData) {
|
||||||
|
pefree(p->pData, ht->persistent);
|
||||||
|
}
|
||||||
|
pefree(p, ht->persistent);
|
||||||
|
}
|
||||||
|
pefree(ht->arBuckets, ht->persistent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void zend_destroy_rsrc_plist(ELS_D)
|
void zend_destroy_rsrc_plist(ELS_D)
|
||||||
{
|
{
|
||||||
zend_hash_reverse_destroy(&EG(persistent_list));
|
zend_hash_reverse_destroy(&EG(persistent_list));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue