com gtk/php-gtk: Fix a nasty and convoluted crash bug that occurs when we have to create an internal class for a GType at runtime *and* there are any userspace classes declared.: main/phpg_support.c

[email protected] (David Soria Parra) Sat, 29 Oct 2005 20:45:38 +0000
Newsgroups php.gtk.cvs
Message-ID <[email protected]>
Commit:    89f63722000cff179021adeecd13110164337b80
Author:    Andrei Zmievski <[email protected]>         Sat, 29 Oct 2005 20:45:38 +0000
Parents:   35eddb95bf1b5ba8195a3409613b92405429fe00
Branches:  master

Link:       http://git.php.net/?p=gtk/php-gtk.git;a=commitdiff;h=89f63722000cff179021adeecd13110164337b80

Log:
Fix a nasty and convoluted crash bug that occurs when we have to create
an internal class for a GType at runtime *and* there are any userspace
classes declared.

Changed paths:
  M  main/phpg_support.c


Diff:
89f63722000cff179021adeecd13110164337b80
diff --git a/main/phpg_support.c b/main/phpg_support.c
index f28ec5f..942e04a 100644
--- a/main/phpg_support.c
+++ b/main/phpg_support.c
@@ -50,6 +50,7 @@ zval* phpg_read_property(zval *object, zval *member, int type TSRMLS_DC)
 	}
 
 	if (ret == SUCCESS) {
+        memset(&result, 0, sizeof(zval));
         ZVAL_NULL(&result);
 		ret = pi->read(poh, &result TSRMLS_CC);
 		if (ret == SUCCESS) {
@@ -441,6 +442,23 @@ PHP_GTK_API zend_class_entry* phpg_create_class(GType gtype)
 
     phpg_register_int_constant(ce, "gtype", sizeof("gtype")-1, gtype);
 
+    /*
+     * This is required to trick Zend into performing the global class table cleanup in a
+     * different manner. EG(full_table_cleanup) is 0 normally, and is set to 1 if any
+     * module is loaded via dl(), because the module may register internal classes. When
+     * we register an internal class at runtime, it is added to the end of the class list.
+     * shutdown_executor() has to remove user-declared classes from the class list. It
+     * does it by iterating through the list in reverse order and cleaning up all user
+     * classes until it encounters an internal class, but since we have just added an
+     * internal class at the very end, it stops right away and does not clean up the user
+     * ones. We circumvent it by pretending to be a dynamically loaded module so that the
+     * hash cleanup does not stop on the first internal class and proceeds through the
+     * whole table.
+     *
+     * Whether there is a better way to do it is still to be seen.
+     */
+    EG(full_tables_cleanup) = 1;
+
     return ce;
 }
 /* }}} */