]> granicus.if.org Git - php/commitdiff
- First destructor hell fix. There was a situation where an object's
authorAndi Gutmans <andi@php.net>
Fri, 25 Jan 2002 12:55:03 +0000 (12:55 +0000)
committerAndi Gutmans <andi@php.net>
Fri, 25 Jan 2002 12:55:03 +0000 (12:55 +0000)
- destructor could be run after its class was already dead. Right now
- object destructors is the first thing whic happens during shutdown in
- order to prevent this problem. It's very likely that destructors will
- cause more grief and we'll have to outline exactly when you should use
- them and what kind of logic you're allowed to do inside of them.
- This bug was reported by sebastian.

Zend/zend_compile.c
Zend/zend_execute_API.c
Zend/zend_objects.c
Zend/zend_objects.h
Zend/zend_opcode.c

index 2a02ac60f65d8c91af4450cebaab67c1bcb85427..0132bb9ab02cd432290fb635038d954df71a7047 100644 (file)
@@ -1365,7 +1365,7 @@ static void create_class(HashTable *class_table, char *name, int name_length, ze
        zend_hash_init(&new_class_entry.function_table, 10, NULL, ZEND_FUNCTION_DTOR, 0);
        zend_hash_init(&new_class_entry.class_table, 10, NULL, ZEND_CLASS_DTOR, 0);
        zend_hash_init(&new_class_entry.default_properties, 10, NULL, ZVAL_PTR_DTOR, 0);
-       new_class_entry.static_members = (HashTable *) emalloc(sizeof(HashTable));
+       ALLOC_HASHTABLE(new_class_entry.static_members);
        zend_hash_init(new_class_entry.static_members, 10, NULL, ZVAL_PTR_DTOR, 0);
        zend_hash_init(&new_class_entry.constants_table, 10, NULL, ZVAL_PTR_DTOR, 0);
 
@@ -1854,7 +1854,7 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
        zend_hash_init(&new_class_entry.function_table, 10, NULL, ZEND_FUNCTION_DTOR, 0);
        zend_hash_init(&new_class_entry.class_table, 10, NULL, ZEND_CLASS_DTOR, 0);
        zend_hash_init(&new_class_entry.default_properties, 10, NULL, ZVAL_PTR_DTOR, 0);
-       new_class_entry.static_members = (HashTable *) emalloc(sizeof(HashTable));
+       ALLOC_HASHTABLE(new_class_entry.static_members);
        zend_hash_init(new_class_entry.static_members, 10, NULL, ZVAL_PTR_DTOR, 0);
        zend_hash_init(&new_class_entry.constants_table, 10, NULL, ZVAL_PTR_DTOR, 0);
 
index 12d28b1789d4a6206d16344ae69d5f0c309b0889..e116a5ca03d3c41af9dcdb95c83d838645a1b99d 100644 (file)
@@ -181,6 +181,8 @@ void init_executor(TSRMLS_D)
 void shutdown_executor(TSRMLS_D)
 {
        zend_try {
+               zend_objects_call_destructors(&EG(objects) TSRMLS_CC);
+
                zend_ptr_stack_destroy(&EG(arg_types_stack));
                                
                while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
index 4ff6bab9214f9da728266c2025c85dbf4f605a73..bdb77f05d0175f32fac65a5753a96accd8dc1b97 100644 (file)
@@ -27,7 +27,7 @@ void zend_objects_destroy(zend_objects *objects)
        efree(objects->object_buckets);
 }
 
-static inline void zend_objects_destroy_object(zend_object *object, zend_object_handle handle TSRMLS_DC)
+static inline void zend_objects_call_destructor(zend_object *object, zend_object_handle handle TSRMLS_DC)
 {
        if (object->ce->destructor) {
                zval *obj;
@@ -57,13 +57,33 @@ static inline void zend_objects_destroy_object(zend_object *object, zend_object_
                zval_ptr_dtor(&destructor_func_name);
                zval_ptr_dtor(&retval_ptr);
        }
+}
 
+
+static inline void zend_objects_destroy_object(zend_object *object, zend_object_handle handle TSRMLS_DC)
+{
+       zend_objects_call_destructor(object, handle TSRMLS_CC);
        /* Nuke the object */
        zend_hash_destroy(object->properties);
        efree(object->properties);
        
 }
 
+
+void zend_objects_call_destructors(zend_objects *objects TSRMLS_DC)
+{
+       int i = 1;
+
+       for (i = 0; i < objects->top ; i++) {
+               if (EG(objects).object_buckets[i].valid) {
+                       EG(objects).object_buckets[i].constructor_called = 1;
+                       zend_objects_destroy_object(&EG(objects).object_buckets[i].bucket.obj.object, i TSRMLS_CC);
+                       EG(objects).object_buckets[i].valid = 0;
+               }
+       }
+}
+
+
 zend_object_value zend_objects_new(zend_object **object, zend_class_entry *class_type)
 {
        zend_object_handle handle;
index b649163007733a3d8b008b8f176874854e56615a..f068afa8f7291275f25938aba6a430fbe7d875a7 100644 (file)
@@ -25,6 +25,7 @@ typedef struct _zend_objects {
 } zend_objects;
 
 void zend_objects_init(zend_objects *objects, zend_uint init_size);
+void zend_objects_call_destructors(zend_objects *objects TSRMLS_DC);
 void zend_objects_destroy(zend_objects *objects);
 zend_object_value zend_objects_new(zend_object **object, zend_class_entry *class_type);
 zend_object *zend_objects_get_address(zend_object_handle handle);
index d79e0f7b22014f982a7b7dd0362c732218f9775e..85e5904b11610ee7f1c2cdd8b5c068c5a551cf0e 100644 (file)
@@ -111,21 +111,21 @@ ZEND_API void destroy_zend_class(zend_class_entry *ce)
        }
        switch (ce->type) {
                case ZEND_USER_CLASS:
+                       zend_hash_destroy(&ce->default_properties);
+                       zend_hash_destroy(ce->static_members);
                        efree(ce->name);
                        efree(ce->refcount);
                        zend_hash_destroy(&ce->function_table);
-                       zend_hash_destroy(&ce->default_properties);
-                       zend_hash_destroy(ce->static_members);
-                       efree(ce->static_members);
+                       FREE_HASHTABLE(ce->static_members);
                        zend_hash_destroy(&ce->constants_table);
                        zend_hash_destroy(&ce->class_table);
                        break;
                case ZEND_INTERNAL_CLASS:
+                       zend_hash_destroy(&ce->default_properties);
+                       zend_hash_destroy(ce->static_members);
                        free(ce->name);
                        free(ce->refcount);
                        zend_hash_destroy(&ce->function_table);
-                       zend_hash_destroy(&ce->default_properties);
-                       zend_hash_destroy(ce->static_members);
                        free(ce->static_members);
                        zend_hash_destroy(&ce->constants_table);
                        zend_hash_destroy(&ce->class_table);