Hi,

Attached is a fix for bug #25543 (Error in set_error_handler() definition), 
which is caused by disordered scheduling of the garbage collection 
(zend_clean_garbage()).

With this patch I'm adding the following two inline functions, 
zend_begin_atomic() and zend_end_atomic(), to prevent GC from being 
performed at the right time. Calls to those functions are inserted 
at the beginning / end of zend_fetch_dimension_address(), 
zend_fetch_property_address(), and some other functions of the same kind.

I'll commit these shortly if you don't see any problem.

Regards,

Moriyoshi
Index: Zend/zend.c
===================================================================
RCS file: /repository/Zend/Attic/zend.c,v
retrieving revision 1.162.2.13
diff -u -r1.162.2.13 zend.c
--- Zend/zend.c 22 Sep 2003 04:22:06 -0000      1.162.2.13
+++ Zend/zend.c 3 Oct 2003 00:13:47 -0000
@@ -501,6 +501,7 @@
        zend_startup_constants();
        zend_set_default_compile_time_values(TSRMLS_C);
        EG(user_error_handler) = NULL;
+       EG(atomic_op_count) = 0;
 #endif
        zend_register_standard_constants(TSRMLS_C);
 
Index: Zend/zend_execute.c
===================================================================
RCS file: /repository/Zend/Attic/zend_execute.c,v
retrieving revision 1.316.2.22
diff -u -r1.316.2.22 zend_execute.c
--- Zend/zend_execute.c 28 Aug 2003 16:08:11 -0000      1.316.2.22
+++ Zend/zend_execute.c 3 Oct 2003 00:13:48 -0000
@@ -739,9 +739,11 @@
        zval *container;
        zval ***retval = &Ts[result->u.var].var.ptr_ptr;
 
+       zend_begin_atomic(TSRMLS_C);
 
        if (container_ptr == NULL) {
                fetch_overloaded_element(result, op1, op2, Ts, type, retval, 
OE_IS_ARRAY TSRMLS_CC);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
 
@@ -750,6 +752,7 @@
        if (container == EG(error_zval_ptr)) {
                *retval = &EG(error_zval_ptr);
                SELECTIVE_PZVAL_LOCK(**retval, result);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
 
@@ -824,7 +827,6 @@
                                Ts[result->u.var].EA.type = IS_STRING_OFFSET;
                                FREE_OP(Ts, op2, EG(free_op2));
                                *retval = NULL;
-                               return;
                        }
                        break;
                default: {
@@ -844,6 +846,7 @@
                        }
                        break;
        }
+       zend_end_atomic(TSRMLS_C);
 }
 
 
@@ -869,9 +872,11 @@
        zval *container;
        zval ***retval = &Ts[result->u.var].var.ptr_ptr;
 
+       zend_begin_atomic(TSRMLS_C);
 
        if (container_ptr == NULL) {
                fetch_overloaded_element(result, op1, op2, Ts, type, retval, 
OE_IS_OBJECT TSRMLS_CC);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
 
@@ -879,6 +884,7 @@
        if (container == EG(error_zval_ptr)) {
                *retval = &EG(error_zval_ptr);
                SELECTIVE_PZVAL_LOCK(**retval, result);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
 
@@ -899,6 +905,7 @@
                
zend_llist_add_element(Ts[result->u.var].EA.data.overloaded_element.elements_list, 
&overloaded_element);
                Ts[result->u.var].EA.type = IS_OVERLOADED_OBJECT;
                *retval = NULL;
+               zend_end_atomic(TSRMLS_C);
                return;
        }
 
@@ -929,6 +936,7 @@
                        *retval = &EG(error_zval_ptr);
                }
                SELECTIVE_PZVAL_LOCK(**retval, result);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
 
@@ -939,6 +947,7 @@
        }
        *retval = zend_fetch_property_address_inner(Z_OBJPROP_P(container), op2, Ts, 
type TSRMLS_CC);
        SELECTIVE_PZVAL_LOCK(**retval, result);
+       zend_end_atomic(TSRMLS_C);
 }
 
 
Index: Zend/zend_execute.h
===================================================================
RCS file: /repository/Zend/Attic/zend_execute.h,v
retrieving revision 1.47.2.1
diff -u -r1.47.2.1 zend_execute.h
--- Zend/zend_execute.h 31 Dec 2002 16:23:00 -0000      1.47.2.1
+++ Zend/zend_execute.h 3 Oct 2003 00:13:48 -0000
@@ -112,6 +112,15 @@
 
 void execute_new_code(TSRMLS_D);
 
+static inline void zend_begin_atomic(TSRMLS_D)
+{
+       EG(atomic_op_count)++;
+}
+
+static inline void zend_end_atomic(TSRMLS_D)
+{
+       EG(atomic_op_count)--;
+}
 
 /* services */
 ZEND_API char *get_active_function_name(TSRMLS_D);
Index: Zend/zend_execute_locks.h
===================================================================
RCS file: /repository/Zend/Attic/zend_execute_locks.h,v
retrieving revision 1.9
diff -u -r1.9 zend_execute_locks.h
--- Zend/zend_execute_locks.h   31 Aug 2001 19:32:25 -0000      1.9
+++ Zend/zend_execute_locks.h   3 Oct 2003 00:13:48 -0000
@@ -22,8 +22,10 @@
 
 static inline void zend_clean_garbage(TSRMLS_D)
 {
-       while (EG(garbage_ptr)) {
-               zval_ptr_dtor(&EG(garbage)[--EG(garbage_ptr)]);
+       if (!EG(atomic_op_count)) {
+               while (EG(garbage_ptr)) {
+                       zval_ptr_dtor(&EG(garbage)[--EG(garbage_ptr)]);
+               }
        }
 }
 
Index: Zend/zend_globals.h
===================================================================
RCS file: /repository/Zend/Attic/zend_globals.h,v
retrieving revision 1.93.2.4
diff -u -r1.93.2.4 zend_globals.h
--- Zend/zend_globals.h 31 May 2003 01:37:43 -0000      1.93.2.4
+++ Zend/zend_globals.h 3 Oct 2003 00:13:48 -0000
@@ -210,6 +210,8 @@
        /* locale stuff */
        char float_separator[1];
 
+       int atomic_op_count;
+
        void *reserved[ZEND_MAX_RESERVED_RESOURCES];
 };
 
Index: Zend/zend.c
===================================================================
RCS file: /repository/ZendEngine2/zend.c,v
retrieving revision 1.252
diff -u -r1.252 zend.c
--- Zend/zend.c 22 Sep 2003 04:21:44 -0000      1.252
+++ Zend/zend.c 3 Oct 2003 00:17:36 -0000
@@ -618,6 +618,7 @@
        zend_set_default_compile_time_values(TSRMLS_C);
        EG(user_error_handler) = NULL;
        EG(user_exception_handler) = NULL;
+       EG(atomic_op_count) = 0;
 #endif
        register_standard_class(TSRMLS_C);
        zend_register_standard_constants(TSRMLS_C);
Index: Zend/zend_execute.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute.c,v
retrieving revision 1.540
diff -u -r1.540 zend_execute.c
--- Zend/zend_execute.c 17 Sep 2003 11:06:11 -0000      1.540
+++ Zend/zend_execute.c 3 Oct 2003 00:17:37 -0000
@@ -71,8 +71,10 @@
 
 static inline void zend_clean_garbage(TSRMLS_D)
 {
-       while (EG(garbage_ptr)) {
-               zval_ptr_dtor(&EG(garbage)[--EG(garbage_ptr)]);
+       if (!EG(atomic_op_count)) {
+               while (EG(garbage_ptr)) {
+                       zval_ptr_dtor(&EG(garbage)[--EG(garbage_ptr)]);
+               }
        }
 }
 
@@ -827,6 +829,8 @@
        zval *container;
        zval ***retval = &T(result->u.var).var.ptr_ptr;
 
+       zend_begin_atomic(TSRMLS_C);
+
        if (!container_ptr) {
                if (T(op1->u.var).EA.type == IS_STRING_OFFSET) {
                        zend_error(E_WARNING, "Cannot use string offset as an array");
@@ -836,6 +840,7 @@
                }
                *retval = &EG(error_zval_ptr);
                SELECTIVE_PZVAL_LOCK(**retval, result);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
        
@@ -844,6 +849,7 @@
        if (container == EG(error_zval_ptr)) {
                *retval = &EG(error_zval_ptr);
                SELECTIVE_PZVAL_LOCK(**retval, result);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
 
@@ -918,7 +924,6 @@
                                T(result->u.var).EA.type = IS_STRING_OFFSET;
                                FREE_OP(Ts, op2, EG(free_op2));
                                *retval = NULL;
-                               return;
                        }
                        break;
                case IS_OBJECT:
@@ -951,6 +956,7 @@
                        }
                        break;
        }
+       zend_end_atomic(TSRMLS_C);
 }
 
 
@@ -974,11 +980,14 @@
        zval **container_ptr = get_obj_zval_ptr_ptr(op1, Ts, type TSRMLS_CC);
        zval *container;
        zval ***retval = &T(result->u.var).var.ptr_ptr;
+
+       zend_begin_atomic(TSRMLS_C);
        
        container = *container_ptr;
        if (container == EG(error_zval_ptr)) {
                *retval = &EG(error_zval_ptr);
                SELECTIVE_PZVAL_LOCK(**retval, result);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
        /* this should modify object only if it's empty */
@@ -1006,6 +1015,7 @@
                        *retval = &EG(error_zval_ptr);
                }
                SELECTIVE_PZVAL_LOCK(**retval, result);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
        
@@ -1016,6 +1026,7 @@
        }
        *retval = zend_fetch_property_address_inner(container, op2, Ts, type 
TSRMLS_CC);
        SELECTIVE_PZVAL_LOCK(**retval, result);
+       zend_end_atomic(TSRMLS_C);
 }
 
 static void zend_fetch_property_address_read(znode *result, znode *op1, znode *op2, 
temp_variable *Ts, int type TSRMLS_DC)
@@ -1026,14 +1037,16 @@
        retval = &T(result->u.var).var.ptr;
        T(result->u.var).var.ptr_ptr = retval;
 
+       zend_begin_atomic(TSRMLS_C);
+
        container = get_obj_zval_ptr(op1, Ts, &EG(free_op1), type TSRMLS_CC);
 
        if (container == EG(error_zval_ptr)) {
                *retval = EG(error_zval_ptr);
                SELECTIVE_PZVAL_LOCK(*retval, result);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
-
        
        if (container->type != IS_OBJECT) {
                zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -1072,7 +1085,7 @@
        }
        
        SELECTIVE_PZVAL_LOCK(*retval, result);
-       return;
+       zend_end_atomic(TSRMLS_C);
 }
 
 static void zend_pre_incdec_property(znode *result, znode *op1, znode *op2, 
temp_variable * Ts, int (*incdec_op)(zval *) TSRMLS_DC)
@@ -1083,6 +1096,8 @@
        zval **retval = &T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
+       zend_begin_atomic(TSRMLS_C);
+
        make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if 
it's empty */
        object = *object_ptr;
        
@@ -1092,6 +1107,7 @@
                *retval = EG(uninitialized_zval_ptr);
 
                SELECTIVE_PZVAL_LOCK(*retval, result);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
        
@@ -1120,6 +1136,7 @@
        }
        
        FREE_OP(Ts, op2, EG(free_op2));
+       zend_end_atomic(TSRMLS_C);
 }
 
 static void zend_post_incdec_property(znode *result, znode *op1, znode *op2, 
temp_variable * Ts, int (*incdec_op)(zval *) TSRMLS_DC)
@@ -1130,6 +1147,8 @@
        zval *retval = &T(result->u.var).tmp_var;
        int have_get_ptr = 0;
 
+       zend_begin_atomic(TSRMLS_C);
+
        make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if 
it's empty */
        object = *object_ptr;
        
@@ -1137,6 +1156,7 @@
                zend_error(E_WARNING, "Attempt to increment/decrement property of 
non-object");
                FREE_OP(Ts, op2, EG(free_op2));
                *retval = *EG(uninitialized_zval_ptr);
+               zend_end_atomic(TSRMLS_C);
                return;
        }
        
@@ -1169,6 +1189,7 @@
        }
        
        FREE_OP(Ts, op2, EG(free_op2));
+       zend_end_atomic(TSRMLS_C);
 }
 
 
Index: Zend/zend_execute.h
===================================================================
RCS file: /repository/ZendEngine2/zend_execute.h,v
retrieving revision 1.58
diff -u -r1.58 zend_execute.h
--- Zend/zend_execute.h 24 Aug 2003 13:10:02 -0000      1.58
+++ Zend/zend_execute.h 3 Oct 2003 00:17:37 -0000
@@ -138,6 +138,15 @@
 
 void execute_new_code(TSRMLS_D);
 
+static inline void zend_begin_atomic(TSRMLS_D)
+{
+       EG(atomic_op_count)++;
+}
+
+static inline void zend_end_atomic(TSRMLS_D)
+{
+       EG(atomic_op_count)--;
+}
 
 /* services */
 ZEND_API char *get_active_function_name(TSRMLS_D);
Index: Zend/zend_globals.h
===================================================================
RCS file: /repository/ZendEngine2/zend_globals.h,v
retrieving revision 1.128
diff -u -r1.128 zend_globals.h
--- Zend/zend_globals.h 11 Aug 2003 05:24:41 -0000      1.128
+++ Zend/zend_globals.h 3 Oct 2003 00:17:38 -0000
@@ -234,6 +234,8 @@
        /* locale stuff */
        char float_separator[1];
 
+       int atomic_op_count;
+
        void *reserved[ZEND_MAX_RESERVED_RESOURCES];
 };
 
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to