From 639f2c8dafe86ff5d04996bd64cce879cc0dedd3 Mon Sep 17 00:00:00 2001 From: Tautvydas Andrikys Date: Thu, 9 Aug 2018 20:16:56 +0300 Subject: [PATCH 1/6] Fixes to run on PHP 7.3: - GC_REFCOUNT => GC_ADDREF - Now handlers are stored in internal cache instead of destructors --- wr_store.c | 28 +++++++++++++++++----------- wr_store.h | 7 +------ wr_weakref.c | 5 ++++- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/wr_store.c b/wr_store.c index 3557e2b..c3bae46 100644 --- a/wr_store.c +++ b/wr_store.c @@ -32,7 +32,7 @@ void wr_store_init() /* {{{ */ { wr_store *store = emalloc(sizeof(wr_store)); - zend_hash_init(&store->old_dtors, 0, NULL, NULL, 0); + zend_hash_init(&store->old_handlers, 0, NULL, NULL, 0); zend_hash_init(&store->objs, 0, NULL, NULL, 0); WR_G(store) = store; @@ -41,14 +41,16 @@ void wr_store_init() /* {{{ */ void wr_store_destroy() /* {{{ */ { wr_store *store = WR_G(store); - zend_object_dtor_obj_t orig_dtor; + zend_object_handlers* orig_handlers; ulong key; - ZEND_HASH_FOREACH_NUM_KEY_PTR(&store->old_dtors, key, orig_dtor) { - ((zend_object_handlers *)key)->dtor_obj = orig_dtor; + ZEND_HASH_FOREACH_NUM_KEY_PTR(&store->old_handlers, key, orig_handlers) { + zend_object* orig_object = (zend_object *)key; + efree((zend_object_handlers*)orig_object->handlers); + orig_object->handlers = orig_handlers; } ZEND_HASH_FOREACH_END(); - zend_hash_destroy(&store->old_dtors); + zend_hash_destroy(&store->old_handlers); zend_hash_destroy(&store->objs); efree(store); @@ -61,12 +63,12 @@ void wr_store_destroy() /* {{{ */ void wr_store_tracked_object_dtor(zend_object *ref_obj) /* {{{ */ { wr_store *store = WR_G(store); - zend_object_dtor_obj_t orig_dtor = zend_hash_index_find_ptr(&store->old_dtors, (ulong)ref_obj->handlers); + zend_object_handlers *orig_handlers = zend_hash_index_find_ptr(&store->old_handlers, (ulong)ref_obj); ulong handle_key = ref_obj->handle; wr_ref_list *list_entry; /* Original dtor has been called, we invalidate the necessary weakrefs: */ - orig_dtor(ref_obj); + orig_handlers->dtor_obj(ref_obj); if ((list_entry = zend_hash_index_find_ptr(&store->objs, handle_key)) != NULL) { /* Invalidate wrefs_head while dtoring, to prevent detach on same wr */ @@ -89,12 +91,16 @@ void wr_store_tracked_object_dtor(zend_object *ref_obj) /* {{{ */ void wr_store_track(zend_object *wref_obj, wr_ref_dtor dtor, zend_object *ref_obj) /* {{{ */ { wr_store *store = WR_G(store); - ulong handlers_key = (ulong)ref_obj->handlers; + ulong handlers_key = (ulong)ref_obj; ulong handle_key = ref_obj->handle; - if (zend_hash_index_find_ptr(&store->old_dtors, handlers_key) == NULL) { - zend_hash_index_update_ptr(&store->old_dtors, handlers_key, ref_obj->handlers->dtor_obj); - ((zend_object_handlers *)ref_obj->handlers)->dtor_obj = wr_store_tracked_object_dtor; + if (zend_hash_index_find_ptr(&store->old_handlers, handlers_key) == NULL) { + size_t size = sizeof(zend_object_handlers); + zend_hash_index_update_ptr(&store->old_handlers, handlers_key, ref_obj->handlers); + zend_object_handlers* handlers = emalloc(size); + memcpy(handlers, ref_obj->handlers, size); + handlers->dtor_obj = wr_store_tracked_object_dtor; + ref_obj->handlers = handlers; } wr_ref_list *tail = zend_hash_index_find_ptr(&store->objs, handle_key); diff --git a/wr_store.h b/wr_store.h index 8da1843..a5f9b80 100644 --- a/wr_store.h +++ b/wr_store.h @@ -37,14 +37,9 @@ typedef struct _wr_ref_list { struct _wr_ref_list *next; } wr_ref_list; -typedef struct _wr_store_data { - zend_object_dtor_obj_t orig_dtor; - wr_ref_list *wrefs_head; -} wr_store_data; - typedef struct _wr_store { HashTable objs; - HashTable old_dtors; + HashTable old_handlers; } wr_store; void wr_store_init(TSRMLS_D); diff --git a/wr_weakref.c b/wr_weakref.c index b7eb7e6..8d56b20 100644 --- a/wr_weakref.c +++ b/wr_weakref.c @@ -38,13 +38,16 @@ static inline wr_weakref_object* wr_weakref_fetch(zend_object *obj) { #define Z_WEAKREF_OBJ_P(zv) wr_weakref_fetch(Z_OBJ_P(zv)); +#if PHP_VERSION_ID < 70300 +#define GC_ADDREF(p) ++GC_REFCOUNT(p) +#endif static int wr_weakref_ref_acquire(wr_weakref_object *wref) /* {{{ */ { if (wref->valid) { if (wref->acquired == 0) { // From now on we hold a proper reference - GC_REFCOUNT(wref->ref_obj)++; + GC_ADDREF(wref->ref_obj); } wref->acquired++; return SUCCESS; From e07b300f50699ff79978be31b1efae57d49022a2 Mon Sep 17 00:00:00 2001 From: Tautvydas Andrikys Date: Thu, 9 Aug 2018 20:38:51 +0300 Subject: [PATCH 2/6] Fixes to run on PHP 7.3: - GC_REFCOUNT => GC_ADDREF - Now handlers are stored in internal cache instead of destructors - Fix to properly destroy created handlers and free up memory --- wr_store.c | 16 ++++++++++++---- wr_store.h | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/wr_store.c b/wr_store.c index c3bae46..9cdbfb3 100644 --- a/wr_store.c +++ b/wr_store.c @@ -38,6 +38,12 @@ void wr_store_init() /* {{{ */ WR_G(store) = store; } /* }}} */ + +void wr_store_restore_handlers(zend_object *object, zend_object_handlers* handlers) { + efree((zend_object_handlers*)object->handlers); + object->handlers = handlers; +} + void wr_store_destroy() /* {{{ */ { wr_store *store = WR_G(store); @@ -45,9 +51,7 @@ void wr_store_destroy() /* {{{ */ ulong key; ZEND_HASH_FOREACH_NUM_KEY_PTR(&store->old_handlers, key, orig_handlers) { - zend_object* orig_object = (zend_object *)key; - efree((zend_object_handlers*)orig_object->handlers); - orig_object->handlers = orig_handlers; + wr_store_restore_handlers((zend_object *)key, orig_handlers); } ZEND_HASH_FOREACH_END(); zend_hash_destroy(&store->old_handlers); @@ -63,13 +67,17 @@ void wr_store_destroy() /* {{{ */ void wr_store_tracked_object_dtor(zend_object *ref_obj) /* {{{ */ { wr_store *store = WR_G(store); - zend_object_handlers *orig_handlers = zend_hash_index_find_ptr(&store->old_handlers, (ulong)ref_obj); + ulong handlers_key = (ulong)ref_obj; + zend_object_handlers *orig_handlers = zend_hash_index_find_ptr(&store->old_handlers, handlers_key); ulong handle_key = ref_obj->handle; wr_ref_list *list_entry; /* Original dtor has been called, we invalidate the necessary weakrefs: */ orig_handlers->dtor_obj(ref_obj); + wr_store_restore_handlers((zend_object *)handlers_key, orig_handlers); + zend_hash_index_del(&store->old_handlers, handlers_key); + if ((list_entry = zend_hash_index_find_ptr(&store->objs, handle_key)) != NULL) { /* Invalidate wrefs_head while dtoring, to prevent detach on same wr */ zend_hash_index_del(&store->objs, handle_key); diff --git a/wr_store.h b/wr_store.h index a5f9b80..71e8479 100644 --- a/wr_store.h +++ b/wr_store.h @@ -47,6 +47,7 @@ void wr_store_destroy(TSRMLS_D); void wr_store_tracked_object_dtor(zend_object *ref_obj); void wr_store_track(zend_object *wref_obj, wr_ref_dtor dtor, zend_object *ref_obj); void wr_store_untrack(zend_object *wref_obj, zend_object *ref_obj); +void wr_store_restore_handlers(zend_object *object, zend_object_handlers* orig_handlers) #endif /* PHP_WEAKREF_H */ From 4f2884e6bb9ccf69eb7e60bc5c50d475ffe2b585 Mon Sep 17 00:00:00 2001 From: Tautvydas Andrikys Date: Thu, 9 Aug 2018 20:42:14 +0300 Subject: [PATCH 3/6] Updated version and changelog --- package.xml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/package.xml b/package.xml index 707a84a..dd1d6ea 100644 --- a/package.xml +++ b/package.xml @@ -15,9 +15,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> colder@php.net yes - 2016-12-13 + 2018-08-09 - 0.3.3 + 0.4.0 0.3.1 @@ -25,9 +25,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> beta PHP - -- Restore dtors to prevent crash in multi-requests scenario - + Fixes to run on PHP 7.3 @@ -77,6 +75,12 @@ http://pear.php.net/dtd/package-2.0.xsd"> weakref + + betabeta + 0.4.00.3.1 + 2018-08-09 + Fixes to run on PHP 7.3 + betabeta 0.3.30.3.1 From 755a5f6f5911da8e90da57172d75a910045f5ac0 Mon Sep 17 00:00:00 2001 From: Tautvydas Andrikys Date: Thu, 9 Aug 2018 20:52:27 +0300 Subject: [PATCH 4/6] Formatting fixes Cleaned some dead code --- wr_store.c | 16 ++++++++-------- wr_weakref.c | 32 +------------------------------- 2 files changed, 9 insertions(+), 39 deletions(-) diff --git a/wr_store.c b/wr_store.c index 9cdbfb3..cbb2894 100644 --- a/wr_store.c +++ b/wr_store.c @@ -40,18 +40,18 @@ void wr_store_init() /* {{{ */ void wr_store_restore_handlers(zend_object *object, zend_object_handlers* handlers) { - efree((zend_object_handlers*)object->handlers); - object->handlers = handlers; + efree((zend_object_handlers*)object->handlers); + object->handlers = handlers; } void wr_store_destroy() /* {{{ */ { wr_store *store = WR_G(store); - zend_object_handlers* orig_handlers; + zend_object_handlers* orig_handlers; ulong key; ZEND_HASH_FOREACH_NUM_KEY_PTR(&store->old_handlers, key, orig_handlers) { - wr_store_restore_handlers((zend_object *)key, orig_handlers); + wr_store_restore_handlers((zend_object *)key, orig_handlers); } ZEND_HASH_FOREACH_END(); zend_hash_destroy(&store->old_handlers); @@ -67,15 +67,15 @@ void wr_store_destroy() /* {{{ */ void wr_store_tracked_object_dtor(zend_object *ref_obj) /* {{{ */ { wr_store *store = WR_G(store); - ulong handlers_key = (ulong)ref_obj; - zend_object_handlers *orig_handlers = zend_hash_index_find_ptr(&store->old_handlers, handlers_key); + ulong handlers_key = (ulong)ref_obj; + zend_object_handlers *orig_handlers = zend_hash_index_find_ptr(&store->old_handlers, handlers_key); ulong handle_key = ref_obj->handle; wr_ref_list *list_entry; /* Original dtor has been called, we invalidate the necessary weakrefs: */ - orig_handlers->dtor_obj(ref_obj); + orig_handlers->dtor_obj(ref_obj); - wr_store_restore_handlers((zend_object *)handlers_key, orig_handlers); + wr_store_restore_handlers((zend_object *)handlers_key, orig_handlers); zend_hash_index_del(&store->old_handlers, handlers_key); if ((list_entry = zend_hash_index_find_ptr(&store->objs, handle_key)) != NULL) { diff --git a/wr_weakref.c b/wr_weakref.c index 8d56b20..fadd5f3 100644 --- a/wr_weakref.c +++ b/wr_weakref.c @@ -47,7 +47,7 @@ static int wr_weakref_ref_acquire(wr_weakref_object *wref) /* {{{ */ if (wref->valid) { if (wref->acquired == 0) { // From now on we hold a proper reference - GC_ADDREF(wref->ref_obj); + GC_ADDREF(wref->ref_obj); } wref->acquired++; return SUCCESS; @@ -126,36 +126,6 @@ static zend_object* wr_weakref_object_new_ex(zend_class_entry *ce, zend_object * // NOOP } } - //if (clone_orig && orig) { - //wr_weakref_object *other = (wr_weakref_object *)zend_object_store_get_object(orig); - //if (other->valid) { - // int acquired = 0; - - // intern->valid = other->valid; - // ALLOC_INIT_ZVAL(intern->ref); - // // ZVAL_COPY_VALUE - // intern->ref->value = other->ref->value; - // Z_TYPE_P(intern->ref) = Z_TYPE_P(other->ref); - - // wr_store_track((zend_object *)intern, wr_weakref_ref_dtor, other->ref); - - // for (acquired = 0; acquired < other->acquired; acquired++) { - // wr_weakref_ref_acquire(intern); - // } - - // if (intern->acquired != other->acquired) { - // // shouldn't occur - // zend_throw_exception(spl_ce_RuntimeException, "Failed to correctly acquire clone's reference", 0); - // } - - //} else { - // intern->valid = 0; - // intern->ref_obj = NULL; - // intern->acquired = 0; - //} - //} else { - - //} wref->std.handlers = &wr_handler_WeakRef; From 7791c4ba15cada9bbd605921910114f77e9f2f94 Mon Sep 17 00:00:00 2001 From: Tautvydas Andrikys Date: Thu, 9 Aug 2018 21:02:50 +0300 Subject: [PATCH 5/6] Fixed missing semicolon --- wr_store.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wr_store.h b/wr_store.h index 71e8479..f0f77ba 100644 --- a/wr_store.h +++ b/wr_store.h @@ -47,7 +47,7 @@ void wr_store_destroy(TSRMLS_D); void wr_store_tracked_object_dtor(zend_object *ref_obj); void wr_store_track(zend_object *wref_obj, wr_ref_dtor dtor, zend_object *ref_obj); void wr_store_untrack(zend_object *wref_obj, zend_object *ref_obj); -void wr_store_restore_handlers(zend_object *object, zend_object_handlers* orig_handlers) +void wr_store_restore_handlers(zend_object *object, zend_object_handlers* orig_handlers); #endif /* PHP_WEAKREF_H */ From cfd90ac275552072556c286f692ee7799ad8f9e9 Mon Sep 17 00:00:00 2001 From: Tautvydas Andrikys Date: Thu, 9 Aug 2018 22:14:50 +0300 Subject: [PATCH 6/6] Updated version --- php_weakref.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_weakref.h b/php_weakref.h index f2eb26b..ab5c795 100644 --- a/php_weakref.h +++ b/php_weakref.h @@ -23,7 +23,7 @@ #include -#define PHP_WEAKREF_VERSION "0.3.3" +#define PHP_WEAKREF_VERSION "0.4.0" #ifdef PHP_WIN32 #define WEAKREF_API __declspec(dllexport)