diff options
author | Zeev Suraski <zeev@php.net> | 2001-07-20 14:20:34 +0000 |
---|---|---|
committer | Zeev Suraski <zeev@php.net> | 2001-07-20 14:20:34 +0000 |
commit | 8084d278850b9b4cf4880ed75cf19f04c38b953f (patch) | |
tree | 9a25327a80e28385e284a968651c876d02813ef5 | |
parent | 13ac04b8e504ba5b0d531bee43d602e6980e2e20 (diff) | |
download | php-git-8084d278850b9b4cf4880ed75cf19f04c38b953f.tar.gz |
Implement a more granular shutdown mechanism for the executor -
prevent corruption of constants and missing destructions of resources
-rw-r--r-- | Zend/zend.c | 5 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 56 | ||||
-rw-r--r-- | Zend/zend_list.c | 27 |
3 files changed, 58 insertions, 30 deletions
diff --git a/Zend/zend.c b/Zend/zend.c index 5e911802c9..87717b1984 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -536,9 +536,8 @@ void zend_deactivate(CLS_D ELS_DC) if (setjmp(EG(bailout))==0) { shutdown_scanner(CLS_C); } - if (setjmp(EG(bailout))==0) { - shutdown_executor(ELS_C); - } + /* shutdown_executor() takes care of its own bailout handling */ + shutdown_executor(ELS_C); if (setjmp(EG(bailout))==0) { shutdown_compiler(CLS_C); } diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 435913a916..0e64a38c6c 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -152,49 +152,53 @@ void init_executor(CLS_D ELS_DC) void shutdown_executor(ELS_D) { - zend_ptr_stack_destroy(&EG(arg_types_stack)); - - 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, (void (*)(void *)) zend_extension_deactivator); + if (setjmp(EG(bailout))==0) { + zend_ptr_stack_destroy(&EG(arg_types_stack)); + + 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, (void (*)(void *)) zend_extension_deactivator); - zend_hash_destroy(&EG(symbol_table)); + 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)]); + 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)); + 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); + /* 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 * op arrays are destroyed. */ - clean_non_persistent_constants(); + if (setjmp(EG(bailout))==0) { + clean_non_persistent_constants(); #if ZEND_DEBUG signal(SIGSEGV, original_sigsegv_handler); #endif - zend_hash_destroy(&EG(included_files)); + zend_hash_destroy(&EG(included_files)); - if (EG(user_error_handler)) { - zval_dtor(EG(user_error_handler)); - FREE_ZVAL(EG(user_error_handler)); - } + if (EG(user_error_handler)) { + zval_dtor(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)); + 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); + EG(error_reporting) = EG(orig_error_reporting); + } } diff --git a/Zend/zend_list.c b/Zend/zend_list.c index 5f13b83937..a4a567b26d 100644 --- a/Zend/zend_list.c +++ b/Zend/zend_list.c @@ -231,10 +231,35 @@ int zend_init_rsrc_plist(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) { zend_hash_reverse_destroy(&EG(persistent_list)); |