summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2003-01-29 14:33:18 +0000
committerStanislav Malyshev <stas@php.net>2003-01-29 14:33:18 +0000
commitf73def91ed90dd422124a54ac7e05b670c0f43f0 (patch)
treeadccbe6ab30743519ad9db3f937940cf9bd0623b
parent683cf733bd16b4380481f56ca896ba34243a8ce6 (diff)
downloadphp-git-f73def91ed90dd422124a54ac7e05b670c0f43f0.tar.gz
Fix object destructors:
zend_objects_store_call_destructors is not used anymore, we rely on symbol tables cleaners to destroy all objects.
-rw-r--r--Zend/zend_execute_API.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index e5641f91e2..c842ccc07f 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -189,15 +189,23 @@ void init_executor(TSRMLS_D)
void shutdown_executor(TSRMLS_D)
{
zend_try {
- zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC);
-
zend_ptr_stack_destroy(&EG(arg_types_stack));
-
- while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
+
+/* 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) TSRMLS_CC); */
+
+/* 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 TSRMLS_CC);
zend_hash_destroy(&EG(symbol_table));
@@ -218,6 +226,12 @@ void shutdown_executor(TSRMLS_D)
zend_hash_reverse_apply(EG(function_table), (apply_func_t) is_not_internal_function TSRMLS_CC);
zend_hash_reverse_apply(EG(class_table), (apply_func_t) is_not_internal_class TSRMLS_CC);
}
+
+ 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_end_try();
zend_try {