33
33
static void wr_weakref_ref_dtor (void * ref_object , zend_object_handle ref_handle , zend_object * wref_obj TSRMLS_DC ) { /* {{{ */
34
34
wr_weakref_object * wref = (wr_weakref_object * )wref_obj ;
35
35
wref -> valid = 0 ;
36
- wref -> ref = NULL ;
37
36
}
38
37
/* }}} */
39
38
40
39
static int wr_weakref_ref_acquire (wr_weakref_object * intern TSRMLS_DC ) /* {{{ */
41
40
{
42
41
if (intern -> valid ) {
43
- Z_ADDREF_P (intern -> ref );
42
+ if (intern -> acquired == 0 ) {
43
+ // We need to register that ref so that the object doesn't get collected
44
+ Z_OBJ_HANDLER_P (intern -> ref , add_ref )(intern -> ref TSRMLS_CC );
45
+ }
44
46
intern -> acquired ++ ;
45
47
return SUCCESS ;
46
48
} else {
@@ -52,17 +54,19 @@ static int wr_weakref_ref_acquire(wr_weakref_object *intern TSRMLS_DC) /* {{{ */
52
54
static int wr_weakref_ref_release (wr_weakref_object * intern TSRMLS_DC ) /* {{{ */
53
55
{
54
56
if (intern -> valid && (intern -> acquired > 0 )) {
55
- zval * ref_tmp = intern -> ref ;
56
- zval_ptr_dtor (& ref_tmp );
57
57
intern -> acquired -- ;
58
+ if (intern -> acquired == 0 ) {
59
+ // We need to register that ref so that the object doesn't get collected
60
+ Z_OBJ_HANDLER_P (intern -> ref , del_ref )(intern -> ref TSRMLS_CC );
61
+ }
58
62
return SUCCESS ;
59
63
} else {
60
64
return FAILURE ;
61
65
}
62
66
}
63
67
/* }}} */
64
68
65
- static void wr_weakref_object_free_storage (void * object TSRMLS_DC ) /* {{{ */
69
+ static void wr_weakref_object_free_storage (void * object TSRMLS_DC ZEND_FILE_LINE_DC ) /* {{{ */
66
70
{
67
71
wr_weakref_object * intern = (wr_weakref_object * )object ;
68
72
@@ -78,6 +82,11 @@ static void wr_weakref_object_free_storage(void *object TSRMLS_DC) /* {{{ */
78
82
wr_store_detach ((zend_object * )intern , Z_OBJ_HANDLE_P (intern -> ref ) TSRMLS_CC );
79
83
}
80
84
85
+ if (intern -> ref ) {
86
+ Z_TYPE_P (intern -> ref ) = IS_NULL ;
87
+ zval_ptr_dtor (& intern -> ref );
88
+ }
89
+
81
90
zend_object_std_dtor (& intern -> std TSRMLS_CC );
82
91
83
92
efree (object );
@@ -111,7 +120,8 @@ static zend_object_value wr_weakref_object_new_ex(zend_class_entry *class_type,
111
120
int acquired = 0 ;
112
121
113
122
intern -> valid = other -> valid ;
114
- intern -> ref = other -> ref ;
123
+ ALLOC_INIT_ZVAL (intern -> ref );
124
+ ZVAL_COPY_VALUE (intern -> ref , other -> ref );
115
125
wr_store_attach ((zend_object * )intern , wr_weakref_ref_dtor , other -> ref TSRMLS_CC );
116
126
117
127
for (acquired = 0 ; acquired < other -> acquired ; acquired ++ ) {
@@ -134,7 +144,7 @@ static zend_object_value wr_weakref_object_new_ex(zend_class_entry *class_type,
134
144
intern -> acquired = 0 ;
135
145
}
136
146
137
- retval .handle = zend_objects_store_put (intern , (zend_objects_store_dtor_t )zend_objects_destroy_object , wr_weakref_object_free_storage , NULL TSRMLS_CC );
147
+ retval .handle = zend_objects_store_put (intern , (zend_objects_store_dtor_t )zend_objects_destroy_object , ( zend_objects_free_object_storage_t ) wr_weakref_object_free_storage , NULL TSRMLS_CC );
138
148
retval .handlers = & wr_handler_WeakRef ;
139
149
140
150
return retval ;
@@ -259,9 +269,11 @@ PHP_METHOD(WeakRef, __construct)
259
269
260
270
intern = (wr_weakref_object * )zend_object_store_get_object (object TSRMLS_CC );
261
271
262
- intern -> ref = ref ;
272
+ ALLOC_INIT_ZVAL (intern -> ref );
273
+
274
+ ZVAL_COPY_VALUE (intern -> ref , ref );
263
275
264
- wr_store_attach ((zend_object * )intern , wr_weakref_ref_dtor , ref TSRMLS_CC );
276
+ wr_store_attach ((zend_object * )intern , wr_weakref_ref_dtor , intern -> ref TSRMLS_CC );
265
277
266
278
intern -> valid = 1 ;
267
279
}
0 commit comments