Skip to content

Commit

Permalink
Normalize naming, start cleaning up for php7
Browse files Browse the repository at this point in the history
  • Loading branch information
colder committed Jan 11, 2016
1 parent e63c098 commit b52dfe5
Show file tree
Hide file tree
Showing 10 changed files with 672 additions and 776 deletions.
371 changes: 236 additions & 135 deletions .gdbinit

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion config.m4
Expand Up @@ -4,5 +4,5 @@ PHP_ARG_ENABLE(weakref, enable Weakref suppport,
[ --enable-weakref Enable Weakref])

if test "$PHP_WEAKREF" != "no"; then
PHP_NEW_EXTENSION(weakref, php_weakref.c wr_weakref.c wr_weakmap.c, $ext_shared)
PHP_NEW_EXTENSION(weakref, php_weakref.c wr_store.c wr_weakref.c wr_weakmap.c, $ext_shared)
fi
131 changes: 2 additions & 129 deletions php_weakref.c
Expand Up @@ -26,7 +26,8 @@
#include "zend_exceptions.h"
#include "ext/standard/info.h"
#include "wr_weakref.h"
#include "wr_weakmap.h"
//#include "wr_weakmap.h" FIXME
#include "wr_store.h"
#include "php_weakref.h"

#ifdef ZTS
Expand All @@ -35,133 +36,6 @@ int weakref_globals_id;
zend_weakref_globals weakref_globals;
#endif

void wr_store_init(TSRMLS_D) /* {{{ */
{
wr_store *store = emalloc(sizeof(wr_store));
store->objs = emalloc(sizeof(wr_store_data));
store->size = 1;

WR_G(store) = store;
} /* }}} */

void wr_store_destroy(TSRMLS_D) /* {{{ */
{
wr_store *store = WR_G(store);

if (store->objs != NULL) {
efree(store->objs);
}

efree(store);

WR_G(store) = NULL;
} /* }}} */

void wr_store_dtor(void *ref_object, zend_object_handle ref_handle TSRMLS_DC) /* {{{ */
{
wr_store *store = WR_G(store);
zend_objects_store_dtor_t orig_dtor = store->objs[ref_handle].orig_dtor;
wr_store_data data = store->objs[ref_handle];
wr_ref_list *list_entry;

EG(objects_store).object_buckets[ref_handle].bucket.obj.dtor = data.orig_dtor;

orig_dtor(ref_object, ref_handle TSRMLS_CC);

/* data might have changed if the destructor freed weakrefs, we reload from store */
list_entry = store->objs[ref_handle].wrefs_head;

/* Invalidate wrefs_head while dtoring, to prevent detach on same wr */
store->objs[ref_handle].wrefs_head = NULL;

while (list_entry != NULL) {
wr_ref_list *next = list_entry->next;
list_entry->dtor(ref_object, ref_handle, list_entry->obj TSRMLS_CC);
efree(list_entry);
list_entry = next;
}
}
/* }}} */

void wr_store_attach(zend_object *intern, wr_ref_dtor dtor, zval *ref TSRMLS_DC) /* {{{ */
{
wr_store *store = WR_G(store);
zend_object_handle ref_handle = Z_OBJ_HANDLE_P(ref);
wr_store_data *data = NULL;

while (ref_handle >= store->size) {
store->size <<= 2;
store->objs = erealloc(store->objs, store->size * sizeof(wr_store_data));
}

data = &store->objs[ref_handle];

if (EG(objects_store).object_buckets[ref_handle].bucket.obj.dtor == wr_store_dtor) {
wr_ref_list *next = emalloc(sizeof(wr_ref_list));
next->obj = intern;
next->dtor = dtor;
next->next = NULL;

if (data->wrefs_head) {
wr_ref_list *list_entry = data->wrefs_head;

while (list_entry->next != NULL) {
list_entry = list_entry->next;
}

list_entry->next = next;
} else {
data->wrefs_head = next;
}
} else {
data->orig_dtor = EG(objects_store).object_buckets[ref_handle].bucket.obj.dtor;
EG(objects_store).object_buckets[ref_handle].bucket.obj.dtor = wr_store_dtor;

data->wrefs_head = emalloc(sizeof(wr_ref_list));
data->wrefs_head->obj = intern;
data->wrefs_head->dtor = dtor;
data->wrefs_head->next = NULL;
}
}
/* }}} */

void wr_store_detach(zend_object *intern, zend_object_handle ref_handle TSRMLS_DC) /* {{{ */
{
wr_store *store = WR_G(store);

if (!store) {
// detach() can be called after the store has already been cleaned up,
// depending on the shutdown sequence (i.e. in case of a fatal).
// See tests/weakref_007.phpt
return;
} else {
wr_store_data *data = &store->objs[ref_handle];
wr_ref_list *prev = NULL;
wr_ref_list *cur = data->wrefs_head;

if (!cur) {
// We are detaching from a wr that is being dtored, skip
return;
}

while (cur && cur->obj != intern) {
prev = cur;
cur = cur->next;
}

assert(cur != NULL);

if (prev) {
prev->next = cur->next;
} else {
data->wrefs_head = cur->next;
}

efree(cur);
}
}
/* }}} */

PHP_MINIT_FUNCTION(weakref) /* {{{ */
{
PHP_MINIT(wr_weakref)(INIT_FUNC_ARGS_PASSTHRU);
Expand All @@ -177,7 +51,6 @@ PHP_RINIT_FUNCTION(weakref) /* {{{ */
PHP_RSHUTDOWN_FUNCTION(weakref) /* {{{ */
{
wr_store_destroy(TSRMLS_C);

return SUCCESS;
}
/* }}} */
Expand Down
24 changes: 1 addition & 23 deletions php_weakref.h
Expand Up @@ -36,6 +36,7 @@
#endif

#include "wr_weakref.h"
#include "wr_store.h"

extern zend_module_entry weakref_module_entry;
#define phpext_weakref_ptr &weakref_module_entry
Expand All @@ -46,33 +47,10 @@ PHP_MINIT_FUNCTION(weakref);
PHP_RINIT_FUNCTION(weakref);
PHP_RSHUTDOWN_FUNCTION(weakref);

typedef void (*wr_ref_dtor)(void *ref_object, zend_object_handle ref_handle, zend_object *wref_obj TSRMLS_DC);

typedef struct _wr_ref_list {
zend_object *obj;
wr_ref_dtor dtor;
struct _wr_ref_list *next;
} wr_ref_list;

typedef struct _wr_store_data {
zend_objects_store_dtor_t orig_dtor;
wr_ref_list *wrefs_head;
} wr_store_data;

typedef struct _wr_store {
wr_store_data *objs;
uint size;
} wr_store;

ZEND_BEGIN_MODULE_GLOBALS(weakref)
wr_store *store;
ZEND_END_MODULE_GLOBALS(weakref)

void wr_store_init(TSRMLS_D);
void wr_store_destroy(TSRMLS_D);
void wr_store_dtor(void *object, zend_object_handle ref_handle TSRMLS_DC);
void wr_store_attach(zend_object *intern, wr_ref_dtor dtor, zval *ref TSRMLS_DC);

#ifdef ZTS
#define WR_G(v) TSRMG(weakref_globals_id, zend_weakref_globals *, v)
extern int weakref_globals_id;
Expand Down
168 changes: 168 additions & 0 deletions wr_store.c
@@ -0,0 +1,168 @@
/*
+----------------------------------------------------------------------+
| Weakref |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2011 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Etienne Kneuss <colder@php.net> |
+----------------------------------------------------------------------+
*/

/* $Id$ */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "php.h"
#include "zend_exceptions.h"
#include "ext/standard/info.h"
#include "wr_weakref.h"
#include "php_weakref.h"

void wr_store_init(TSRMLS_D) /* {{{ */
{
wr_store *store = emalloc(sizeof(wr_store));
store->objs = emalloc(sizeof(wr_store_data));
store->size = 1;

WR_G(store) = store;
} /* }}} */

void wr_store_destroy(TSRMLS_D) /* {{{ */
{
wr_store *store = WR_G(store);

if (store->objs != NULL) {
efree(store->objs);
}

efree(store);

WR_G(store) = NULL;
} /* }}} */

/* This function is invoked whenever an object tracked by a weak ref/map is
* destroyed */
void wr_store_tracked_object_dtor(zend_object *ref_obj) /* {{{ */
{
wr_store *store = WR_G(store);
uint32_t ref_handle = ref_obj->handle;
zend_object_dtor_obj_t orig_dtor = store->objs[ref_handle].orig_dtor;


// Not sure if it is really needed, but let's restore the original object
// dtor before calling it.
((zend_object_handlers *) ref_obj->handlers)->dtor_obj = orig_dtor;

orig_dtor(ref_obj);

/* Original dtor has been called, we invalidate the necessary weakrefs: */
wr_ref_list *list_entry = store->objs[ref_handle].wrefs_head;

/* Invalidate wrefs_head while dtoring, to prevent detach on same wr */
store->objs[ref_handle].wrefs_head = NULL;

while (list_entry != NULL) {
wr_ref_list *next = list_entry->next;
list_entry->dtor(list_entry->wref_obj, ref_obj TSRMLS_CC);
efree(list_entry);
list_entry = next;
}
}
/* }}} */

/**
* This function is called when a given weak-ref/map starts tracking the 'ref'
* object.
*/
void wr_store_track(zend_object *wref_obj, wr_ref_dtor dtor, zend_object *ref_obj TSRMLS_DC) /* {{{ */
{
wr_store *store = WR_G(store);

/* Grow store if needed */
while (ref_obj->handle >= store->size) {
store->size *= 2;
store->objs = erealloc(store->objs, store->size * sizeof(wr_store_data));
}

wr_store_data *data = &store->objs[ref_obj->handle];

/* The object in 'ref' needs to have its dtor replaced by
* 'wr_store_tracked_object_dtor' (if it's not there already) */
if (ref_obj->handlers->dtor_obj != wr_store_tracked_object_dtor) {
// FIXME
zend_object_handlers *handlers = (zend_object_handlers *)ref_obj->handlers;
data->orig_dtor = handlers->dtor_obj;
handlers->dtor_obj = wr_store_tracked_object_dtor;
data->wrefs_head = NULL;
}

/* We now put the weakref 'wref' in the list of weak references that need
* to be invalidated when 'ref' is destroyed */
wr_ref_list *new_head = emalloc(sizeof(wr_ref_list));
new_head->wref_obj = wref_obj;
new_head->dtor = dtor;
new_head->next = data->wrefs_head;

data->wrefs_head = new_head;
}
/* }}} */

/**
* This function is called when a given weak-ref/map stops tracking the 'ref'
* object.
*/
void wr_store_untrack(zend_object *wref_obj, zend_object *ref_obj TSRMLS_DC) /* {{{ */
{
wr_store *store = WR_G(store);

if (!store) {
// detach() can be called after the store has already been cleaned up,
// depending on the shutdown sequence (i.e. in case of a fatal).
// See tests/weakref_007.phpt
return;
} else {
wr_store_data *data = &store->objs[ref_obj->handle];
wr_ref_list *prev = NULL;
wr_ref_list *cur = data->wrefs_head;

if (!cur) {
// We are detaching from a wr that is being dtored, skip
return;
}

while (cur && cur->wref_obj != wref_obj) {
prev = cur;
cur = cur->next;
}

assert(cur != NULL);

if (prev) {
prev->next = cur->next;
} else {
data->wrefs_head = cur->next;
}

efree(cur);
}
}
/* }}} */

/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: fdm=marker
* vim: noet sw=4 ts=4
*/

0 comments on commit b52dfe5

Please sign in to comment.