Skip to content
This repository has been archived by the owner on Dec 16, 2019. It is now read-only.

Commit

Permalink
Thread::getCurrentThreadId (static) method
Browse files Browse the repository at this point in the history
Thread::getThreadId inconsistency fixed
Fix memory errors on copying statics/defaults in prepare()
Replace usage of calloc() with malloc() in store routines
Replace usage of calloc() with ecalloc() where buffers are passed into zend
Changes to tests to bring them inline
impact #180
  • Loading branch information
krakjoe committed Oct 9, 2013
1 parent 6eceb56 commit 770bd4e
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 57 deletions.
18 changes: 14 additions & 4 deletions classes/thread.h
Expand Up @@ -28,6 +28,7 @@ PHP_METHOD(Thread, isJoined);
PHP_METHOD(Thread, isWaiting);
PHP_METHOD(Thread, isTerminated);
PHP_METHOD(Thread, getThreadId);
PHP_METHOD(Thread, getCurrentThreadId);
PHP_METHOD(Thread, getCreatorId);

PHP_METHOD(Thread, synchronized);
Expand Down Expand Up @@ -64,6 +65,9 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(Thread_getThreadId, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(Thread_getCurrentThreadId, 0, 0, 0)
ZEND_END_ARG_INFO()


ZEND_BEGIN_ARG_INFO_EX(Thread_getCreatorId, 0, 0, 0)
ZEND_END_ARG_INFO()
Expand Down Expand Up @@ -128,7 +132,8 @@ zend_function_entry pthreads_thread_methods[] = {
PHP_ME(Thread, isWaiting, Thread_isWaiting, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Thread, isTerminated, Thread_isTerminated, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Thread, getTerminationInfo, Thread_getTerminationInfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Thread, getThreadId, Thread_getThreadId, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL|ZEND_ACC_STATIC)
PHP_ME(Thread, getThreadId, Thread_getThreadId, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Thread, getCurrentThreadId, Thread_getCurrentThreadId, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL|ZEND_ACC_STATIC)
PHP_ME(Thread, getCreatorId, Thread_getCreatorId, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Thread, synchronized, Thread_synchronized, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Thread, lock, Thread_lock, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
Expand Down Expand Up @@ -347,9 +352,14 @@ PHP_METHOD(Thread, detach)
Will return the identifier of the referenced Thread */
PHP_METHOD(Thread, getThreadId)
{
if (getThis()) {
ZVAL_LONG(return_value, (PTHREADS_FETCH_FROM(getThis()))->tid);
} else ZVAL_LONG(return_value, pthreads_self());
ZVAL_LONG(return_value, (PTHREADS_FETCH_FROM(getThis()))->tid);
} /* }}} */

/* {{{ proto long Thread::getCurrentThreadId()
Will return the identifier of the current Thread */
PHP_METHOD(Thread, getCurrentThreadId)
{
ZVAL_LONG(return_value, pthreads_self());
} /* }}} */

/* {{{ proto long Thread::getCreatorId()
Expand Down
14 changes: 4 additions & 10 deletions src/object.c
Expand Up @@ -424,8 +424,6 @@ static int pthreads_connect(PTHREAD source, PTHREAD destination TSRMLS_DC) {
destination->thread = source->thread;
destination->tid = source->tid;
destination->tls = source->tls;
destination->cls = source->cls;
destination->cid = source->cid;
destination->address = source->address;
destination->resources = source->resources;
destination->lock = source->lock;
Expand Down Expand Up @@ -464,21 +462,19 @@ static void pthreads_base_ctor(PTHREAD base, zend_class_entry *entry TSRMLS_DC)
#endif

base->cls = tsrm_ls;
base->cid = pthreads_self();
base->address = pthreads_address_alloc(base TSRMLS_CC);
base->options = PTHREADS_INHERIT_ALL;

if (PTHREADS_IS_CONNECTION(base)) {
base->tid = pthreads_self();
} else {
base->cid = pthreads_self();

if (!PTHREADS_IS_CONNECTION(base)) {
base->lock = pthreads_lock_alloc(TSRMLS_C);
base->state = pthreads_state_alloc(0 TSRMLS_CC);
base->synchro = pthreads_synchro_alloc(TSRMLS_C);
base->modifiers = pthreads_modifiers_alloc(TSRMLS_C);
base->store = pthreads_store_alloc(TSRMLS_C);
base->resources = pthreads_resources_alloc(TSRMLS_C);
base->error = pthreads_error_alloc(TSRMLS_C);

pthreads_modifiers_init(base->modifiers, entry TSRMLS_CC);
if (PTHREADS_IS_WORKER(base)) {
base->stack = (pthreads_stack) calloc(1, sizeof(*base->stack));
Expand All @@ -488,8 +484,6 @@ static void pthreads_base_ctor(PTHREAD base, zend_class_entry *entry TSRMLS_DC)
base->stack->position = 0L;
}
}


}
}
} /* }}} */
Expand Down
12 changes: 12 additions & 0 deletions src/pthreads.h
Expand Up @@ -59,6 +59,18 @@ extern zend_class_entry *pthreads_stackable_entry;
extern zend_class_entry *pthreads_mutex_entry;
extern zend_class_entry *pthreads_condition_entry;

#ifndef IS_PTHREADS_CLASS
#define IS_PTHREADS_CLASS(c) \
(instanceof_function(c, pthreads_thread_entry TSRMLS_CC) || \
instanceof_function(c, pthreads_worker_entry TSRMLS_CC) || \
instanceof_function(c, pthreads_stackable_entry TSRMLS_CC))
#endif

#ifndef IS_PTHREADS_OBJECT
#define IS_PTHREADS_OBJECT(o) \
(IS_PTHREADS_CLASS(Z_OBJCE_P(o)))
#endif

extern zend_object_handlers pthreads_handlers;
extern zend_object_handlers *zend_handlers;

Expand Down
96 changes: 55 additions & 41 deletions src/store.c
Expand Up @@ -54,15 +54,15 @@ static void pthreads_store_create(pthreads_storage *storage, zval *pzval, zend_b
static int pthreads_store_convert(pthreads_storage *storage, zval *pzval TSRMLS_DC);
static int pthreads_store_tostring(zval *pzval, char **pstring, size_t *slength, zend_bool complex TSRMLS_DC);
static int pthreads_store_tozval(zval *pzval, char *pstring, size_t slength TSRMLS_DC);
static int pthreads_store_remove_resources_recursive(zval **pzval TSRMLS_DC);
static int pthreads_store_validate_resource(zval **pzval TSRMLS_DC);
static int pthreads_store_remove_resources(zval **pzval TSRMLS_DC);
static int pthreads_store_remove_complex_recursive(zval **pzval TSRMLS_DC);
static int pthreads_store_validate_object(zval **pzval TSRMLS_DC);
static int pthreads_store_remove_complex(zval **pzval TSRMLS_DC);
static void pthreads_store_storage_dtor (pthreads_storage *element);
/* }}} */

/* {{{ allocate storage for an object */
pthreads_store pthreads_store_alloc(TSRMLS_D) {
pthreads_store store = calloc(1, sizeof(*store));
pthreads_store store = malloc(sizeof(*store));

if (store) {
if (zend_hash_init(&store->table, 8, NULL, (dtor_func_t) pthreads_store_storage_dtor, 1)==SUCCESS){
Expand Down Expand Up @@ -189,19 +189,21 @@ int pthreads_store_separate(zval * pzval, zval **separated, zend_bool allocate,
int result = FAILURE;
pthreads_storage storage;

if (allocate) {
MAKE_STD_ZVAL(*separated);
}

if (pzval) {
pthreads_store_create(&storage, pzval, complex TSRMLS_CC);

if (allocate) {
MAKE_STD_ZVAL(*separated);
}


result = pthreads_store_convert(
&storage, *separated TSRMLS_CC);

if (result == SUCCESS)
pthreads_store_storage_dtor(&storage);
}
else Z_TYPE_PP(separated) = IS_NULL;
} else Z_TYPE_PP(separated) = IS_NULL;

return result;
} /* }}} */

Expand Down Expand Up @@ -419,9 +421,9 @@ static void pthreads_store_create(pthreads_storage *storage, zval *unstore, zend

case IS_STRING: {
if ((storage->length = Z_STRLEN_P(unstore))) {
storage->data = (char*) calloc(1, storage->length+1);
memmove(
storage->data, (const void*) Z_STRVAL_P(unstore), storage->length
storage->data = (char*) malloc(storage->length+1);
memcpy(
storage->data, (const void*) Z_STRVAL_P(unstore), storage->length+1
);
}
} break;
Expand All @@ -433,7 +435,7 @@ static void pthreads_store_create(pthreads_storage *storage, zval *unstore, zend

case IS_RESOURCE: {
if (complex) {
pthreads_resource resource = calloc(1, sizeof(*resource));
pthreads_resource resource = malloc(sizeof(*resource));
if (resource) {
resource->scope = EG(scope);
resource->ls = TSRMLS_C;
Expand All @@ -448,7 +450,7 @@ static void pthreads_store_create(pthreads_storage *storage, zval *unstore, zend
}
} break;

case IS_DOUBLE:
case IS_DOUBLE:
storage->simple.dval = Z_DVAL_P(unstore);
break;

Expand Down Expand Up @@ -485,7 +487,7 @@ static int pthreads_store_convert(pthreads_storage *storage, zval *pzval TSRMLS_
} else ZVAL_EMPTY_STRING(pzval);
break;

case IS_NULL: ZVAL_NULL(pzval); break;
case IS_NULL: Z_TYPE_P(pzval) = IS_NULL; break;
case IS_BOOL: ZVAL_BOOL(pzval, storage->simple.lval); break;
case IS_LONG: ZVAL_LONG(pzval, storage->simple.lval); break;
case IS_DOUBLE: ZVAL_DOUBLE(pzval, storage->simple.dval); break;
Expand Down Expand Up @@ -551,9 +553,15 @@ static int pthreads_store_convert(pthreads_storage *storage, zval *pzval TSRMLS_
(char*) storage->data,
storage->length TSRMLS_CC
);
if (result == FAILURE) {
/* display error, do something ... ? */
Z_TYPE_P(pzval) = IS_NULL;
}
} break;

default: ZVAL_NULL(pzval);
default: {
Z_TYPE_P(pzval) = IS_NULL;
}
}
}
return result;
Expand All @@ -563,13 +571,18 @@ static int pthreads_store_convert(pthreads_storage *storage, zval *pzval TSRMLS_
/* {{{ zval to string */
static int pthreads_store_tostring(zval *pzval, char **pstring, size_t *slength, zend_bool complex TSRMLS_DC) {
int result = FAILURE;
if (pzval && (Z_TYPE_P(pzval) != IS_OBJECT || Z_OBJ_P(pzval))) {
smart_str *psmart = (smart_str*) calloc(1, sizeof(smart_str));
if (pzval &&
(Z_TYPE_P(pzval) != IS_NULL) &&
(Z_TYPE_P(pzval) != IS_OBJECT || pthreads_store_validate_object(&pzval TSRMLS_CC))) {

smart_str *psmart = (smart_str*) ecalloc(1, sizeof(smart_str));

if (psmart) {
if (!complex && (Z_TYPE_P(pzval) == IS_OBJECT || Z_TYPE_P(pzval) == IS_ARRAY)) {
pthreads_store_remove_resources_recursive(&pzval TSRMLS_CC);
if (!complex &&
(Z_TYPE_P(pzval) == IS_OBJECT || Z_TYPE_P(pzval) == IS_ARRAY)) {
pthreads_store_remove_complex_recursive(&pzval TSRMLS_CC);
}

{
if ((Z_TYPE_P(pzval) != IS_OBJECT) ||
(Z_OBJCE_P(pzval)->serialize != zend_class_serialize_deny)) {
Expand All @@ -583,20 +596,23 @@ static int pthreads_store_tostring(zval *pzval, char **pstring, size_t *slength,
PHP_VAR_SERIALIZE_DESTROY(vars);
}
}

*slength = psmart->len;
if (psmart->len) {
*pstring = calloc(1, psmart->len+1);
*pstring = malloc(psmart->len+1);
if (*pstring) {
memmove(
memcpy(
(char*) *pstring, (const void*) psmart->c, psmart->len
);
result = SUCCESS;
}
} else *pstring = NULL;
smart_str_free(psmart);
free(psmart);
efree(psmart);
}
} else {
*slength = 0;
*pstring = NULL;
}
return result;
} /* }}} */
Expand Down Expand Up @@ -638,9 +654,7 @@ int pthreads_store_merge(zval *destination, zval *from, zend_bool overwrite TSRM
switch (Z_TYPE_P(from)) {
case IS_OBJECT: {
/* check for a suitable pthreads object */
if (instanceof_function(Z_OBJCE_P(from), pthreads_thread_entry TSRMLS_CC) ||
instanceof_function(Z_OBJCE_P(from), pthreads_worker_entry TSRMLS_CC) ||
instanceof_function(Z_OBJCE_P(from), pthreads_stackable_entry TSRMLS_CC) ) {
if (IS_PTHREADS_OBJECT(from)) {

zend_bool locked[2] = {0, 0};
PTHREAD pobjects[2] = {PTHREADS_FETCH_FROM(destination), PTHREADS_FETCH_FROM(from)};
Expand Down Expand Up @@ -686,8 +700,8 @@ int pthreads_store_merge(zval *destination, zval *from, zend_bool overwrite TSRM

case IS_STRING: {
if ((copy.length = storage->length)) {
copy.data = (char*) calloc(1, copy.length+1);
memmove(
copy.data = (char*) malloc(copy.length+1);
memcpy(
copy.data, (const void*) storage->data, copy.length
);
}
Expand All @@ -701,8 +715,8 @@ int pthreads_store_merge(zval *destination, zval *from, zend_bool overwrite TSRM
case IS_OBJECT:
case IS_ARRAY: {
if ((copy.length = storage->length)) {
copy.data = (char*) calloc(1, copy.length+1);
memmove(
copy.data = (char*) malloc(copy.length+1);
memcpy(
copy.data, (const void*) storage->data, copy.length
);

Expand Down Expand Up @@ -793,21 +807,21 @@ int pthreads_store_merge(zval *destination, zval *from, zend_bool overwrite TSRM
return SUCCESS;
} /* }}} */

/* {{{ set resources to NULL for non-complex types; helper-function for pthreads_store_remove_resources_recursive */
static int pthreads_store_remove_resources(zval **pzval TSRMLS_DC) {
/* {{{ set resources to NULL for non-complex types; helper-function for pthreads_store_remove_complex_recursive */
static int pthreads_store_remove_complex(zval **pzval TSRMLS_DC) {
if (Z_TYPE_PP(pzval) == IS_RESOURCE) {
Z_TYPE_PP(pzval) = IS_NULL;
}
return pthreads_store_remove_resources_recursive(pzval TSRMLS_CC);
return pthreads_store_remove_complex_recursive(pzval TSRMLS_CC);
} /* }}} */

/* {{{ check a handle is valid before reading it */
static int pthreads_store_validate_resource(zval **pzval TSRMLS_DC) {
return (EG(objects_store).top > Z_OBJ_HANDLE_PP(pzval));
static int pthreads_store_validate_object(zval **pzval TSRMLS_DC) {
return (EG(objects_store).top > Z_OBJ_HANDLE_PP(pzval)) && (Z_OBJ_P(*pzval));
} /* }}} */

/* {{{ set corrupt objects (like mysqli after thread duplication) to NULL and recurse */
static int pthreads_store_remove_resources_recursive(zval **pzval TSRMLS_DC) {
static int pthreads_store_remove_complex_recursive(zval **pzval TSRMLS_DC) {
int is_temp;

HashTable *thash = NULL;
Expand All @@ -817,7 +831,7 @@ static int pthreads_store_remove_resources_recursive(zval **pzval TSRMLS_DC) {

case IS_OBJECT:
if (thash == NULL) {
if (!pthreads_store_validate_resource(pzval TSRMLS_CC) || !Z_OBJ_P(*pzval)) {
if (!pthreads_store_validate_object(pzval TSRMLS_CC)) {
GC_REMOVE_ZVAL_FROM_BUFFER(*pzval);
Z_TYPE_PP(pzval) = IS_NULL;
return ZEND_HASH_APPLY_KEEP;
Expand All @@ -826,7 +840,7 @@ static int pthreads_store_remove_resources_recursive(zval **pzval TSRMLS_DC) {
}

if (thash) {
zend_hash_apply(thash, (apply_func_t)pthreads_store_remove_resources TSRMLS_CC);
zend_hash_apply(thash, (apply_func_t)pthreads_store_remove_complex TSRMLS_CC);
}

break;
Expand Down
2 changes: 1 addition & 1 deletion tests/complex-statics-set-null.phpt
Expand Up @@ -6,7 +6,7 @@ class file {
public static $fps;

public static function __callstatic($method, $args) {
$tid = Thread::getThreadId();
$tid = Thread::getCurrentThreadId();
if (isset(self::$fps[$tid])) {
return call_user_func_array(array("file", "_{$method}"), array_merge($args, array($tid)));
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/complex-statics.phpt
Expand Up @@ -8,7 +8,7 @@ class sql {
public static $connection;

public static function __callstatic($method, $args){
$tid = Thread::getThreadId();
$tid = Thread::getCurrentThreadId();
if (isset(self::$connection[$tid])) {
return call_user_func_array(array(self::$connection[$tid], "_{$method}"), $args);
} else {
Expand Down

0 comments on commit 770bd4e

Please sign in to comment.