summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>2001-07-20 14:20:34 +0000
committerZeev Suraski <zeev@php.net>2001-07-20 14:20:34 +0000
commit8084d278850b9b4cf4880ed75cf19f04c38b953f (patch)
tree9a25327a80e28385e284a968651c876d02813ef5
parent13ac04b8e504ba5b0d531bee43d602e6980e2e20 (diff)
downloadphp-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.c5
-rw-r--r--Zend/zend_execute_API.c56
-rw-r--r--Zend/zend_list.c27
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));