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
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)
diff --git a/wr_store.c b/wr_store.c
index 3557e2b..cbb2894 100644
--- a/wr_store.c
+++ b/wr_store.c
@@ -32,23 +32,29 @@ 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;
} /* }}} */
+
+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);
- 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) {
+ wr_store_restore_handlers((zend_object *)key, 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 +67,16 @@ 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);
+ 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_dtor(ref_obj);
+ 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 */
@@ -89,12 +99,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..f0f77ba 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);
@@ -52,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 */
diff --git a/wr_weakref.c b/wr_weakref.c
index b7eb7e6..fadd5f3 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;
@@ -123,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;