From 50a0ea7b8cede077220902733bd4efec59bf41d8 Mon Sep 17 00:00:00 2001 From: Sascha Schumann Date: Thu, 12 Aug 2010 07:58:14 +0000 Subject: [PATCH] separate properties of internal classes in ZTS mode fully, otherwise multiple threads will modify the zvals' contents without any synchronisation. --- Zend/zend_API.c | 2 +- Zend/zend_compile.c | 21 ++------------------- Zend/zend_exceptions.c | 2 +- Zend/zend_objects.c | 2 +- Zend/zend_variables.c | 11 +++++++++++ Zend/zend_variables.h | 11 +++++++++++ 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index f8ce293210..c8707adb6c 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1082,7 +1082,7 @@ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type } else { ALLOC_HASHTABLE_REL(object->properties); zend_hash_init(object->properties, zend_hash_num_elements(&class_type->default_properties), NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(object->properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + zend_hash_copy(object->properties, &class_type->default_properties, zval_copy_property_ctor(class_type), (void *) &tmp, sizeof(zval *)); } } else { Z_OBJVAL_P(arg) = class_type->create_object(class_type TSRMLS_CC); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index e1efca6d16..0ccacbb27d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2817,25 +2817,8 @@ static int inherit_static_prop(zval **p TSRMLS_DC, int num_args, va_list args, c } /* }}} */ -#ifdef ZTS -static void zval_internal_ctor(zval **p) /* {{{ */ -{ - zval *orig_ptr = *p; - - ALLOC_ZVAL(*p); - **p = *orig_ptr; - zval_copy_ctor(*p); - Z_SET_REFCOUNT_PP(p, 1); - Z_UNSET_ISREF_PP(p); -} -/* }}} */ - -# define zval_property_ctor(parent_ce, ce) \ - ((void (*)(void *)) (((parent_ce)->type != (ce)->type) ? zval_internal_ctor : zval_add_ref)) -#else -# define zval_property_ctor(parent_ce, ce) \ - ((void (*)(void *)) zval_add_ref) -#endif +#define zval_property_ctor(parent_ce, ce) \ + ((copy_ctor_func_t) (((parent_ce)->type != (ce)->type) ? zval_shared_property_ctor : zval_add_ref)) ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC) /* {{{ */ { diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 6d2460aef2..178ef50e7c 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -137,7 +137,7 @@ static zend_object_value zend_default_exception_new_ex(zend_class_entry *class_t ALLOC_HASHTABLE(object->properties); zend_hash_init(object->properties, 0, NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(object->properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + zend_hash_copy(object->properties, &class_type->default_properties, zval_copy_property_ctor(class_type), (void *) &tmp, sizeof(zval *)); ALLOC_ZVAL(trace); Z_UNSET_ISREF_P(trace); diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index a2f1d3287e..ed9dc7c76c 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -148,7 +148,7 @@ ZEND_API zend_object *zend_objects_get_address(const zval *zobject TSRMLS_DC) ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object_value new_obj_val, zend_object *old_object, zend_object_handle handle TSRMLS_DC) { - zend_hash_copy(new_object->properties, old_object->properties, (copy_ctor_func_t) zval_add_ref, (void *) NULL /* Not used anymore */, sizeof(zval *)); + zend_hash_copy(new_object->properties, old_object->properties, zval_copy_property_ctor(old_object->ce), (void *) NULL /* Not used anymore */, sizeof(zval *)); if (old_object->ce->clone) { zval *new_obj; diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index dce98ba22c..dd190d8ee2 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -159,6 +159,17 @@ ZEND_API void _zval_dtor_wrapper(zval *zvalue) zval_dtor(zvalue); } +ZEND_API void zval_property_ctor(zval **p) /* {{{ */ +{ + zval *orig_ptr = *p; + + ALLOC_ZVAL(*p); + **p = *orig_ptr; + zval_copy_ctor(*p); + Z_SET_REFCOUNT_PP(p, 1); + Z_UNSET_ISREF_PP(p); +} +/* }}} */ #if ZEND_DEBUG ZEND_API void _zval_copy_ctor_wrapper(zval *zvalue) diff --git a/Zend/zend_variables.h b/Zend/zend_variables.h index 9304a67c0e..0849573039 100644 --- a/Zend/zend_variables.h +++ b/Zend/zend_variables.h @@ -76,6 +76,17 @@ ZEND_API void _zval_internal_ptr_dtor_wrapper(zval **zvalue); ZEND_API void zval_add_ref(zval **p); +ZEND_API void zval_property_ctor(zval **); + +#ifdef ZTS +# define zval_shared_property_ctor zval_property_ctor +#else +# define zval_shared_property_ctor zval_add_ref +#endif + +#define zval_copy_property_ctor(ce) ((copy_ctor_func_t) (ce)->type == ZEND_INTERNAL_CLASS ? zval_shared_property_ctor : zval_add_ref) + + END_EXTERN_C() #define ZVAL_DESTRUCTOR (void (*)(void *)) zval_dtor_wrapper -- 2.40.0