Skip to content

Support for PHP 7.3 #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,17 @@ http://pear.php.net/dtd/package-2.0.xsd">
<email>[email protected]</email>
<active>yes</active>
</lead>
<date>2016-12-13</date>
<date>2018-08-09</date>
<version>
<release>0.3.3</release>
<release>0.4.0</release>
<api>0.3.1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP</license>
<notes>
- Restore dtors to prevent crash in multi-requests scenario
</notes>
<notes>Fixes to run on PHP 7.3</notes>
<contents>
<dir name="/">
<file role='doc' name='CREDITS'/>
Expand Down Expand Up @@ -77,6 +75,12 @@ http://pear.php.net/dtd/package-2.0.xsd">
<providesextension>weakref</providesextension>
<extsrcrelease/>
<changelog>
<release>
<stability><release>beta</release><api>beta</api></stability>
<version><release>0.4.0</release><api>0.3.1</api></version>
<date>2018-08-09</date>
<notes>Fixes to run on PHP 7.3</notes>
</release>
<release>
<stability><release>beta</release><api>beta</api></stability>
<version><release>0.3.3</release><api>0.3.1</api></version>
Expand Down
2 changes: 1 addition & 1 deletion php_weakref.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

#include <php.h>

#define PHP_WEAKREF_VERSION "0.3.3"
#define PHP_WEAKREF_VERSION "0.4.0"

#ifdef PHP_WIN32
#define WEAKREF_API __declspec(dllexport)
Expand Down
36 changes: 25 additions & 11 deletions wr_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 */
Expand All @@ -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);
Expand Down
8 changes: 2 additions & 6 deletions wr_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,17 @@ 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);
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 */

Expand Down
35 changes: 4 additions & 31 deletions wr_weakref.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down