]> granicus.if.org Git - php/commitdiff
Implement a more granular shutdown mechanism for the executor -
authorZeev Suraski <zeev@php.net>
Fri, 20 Jul 2001 14:20:34 +0000 (14:20 +0000)
committerZeev Suraski <zeev@php.net>
Fri, 20 Jul 2001 14:20:34 +0000 (14:20 +0000)
prevent corruption of constants and missing destructions of resources

Zend/zend.c
Zend/zend_execute_API.c
Zend/zend_list.c

index 5e911802c9fca011c2939ddefd5c75175f565ed2..87717b19841559e8f6a94ef484e6400fa00b8287 100644 (file)
@@ -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);
        }
index 435913a9168535c58eb107d74ad8e6d961723193..0e64a38c6cdab3305f6460f5ffc6a8550d7a5966 100644 (file)
@@ -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);
+       }
 }
 
 
index 5f13b8393785e8429d0679e74ac9c2199c56b785..a4a567b26d9ce5772caaa2e13d234d3a79b96372 100644 (file)
@@ -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));