summaryrefslogtreecommitdiff
path: root/ext/rpc/rpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/rpc/rpc.c')
-rw-r--r--ext/rpc/rpc.c93
1 files changed, 42 insertions, 51 deletions
diff --git a/ext/rpc/rpc.c b/ext/rpc/rpc.c
index 1eae43234e..6955d8b545 100644
--- a/ext/rpc/rpc.c
+++ b/ext/rpc/rpc.c
@@ -229,6 +229,11 @@ static void rpc_instance_dtor(void *pDest)
RPC_HT(*intern)->rpc_dtor((*intern)->data);
+ tsrm_mutex_free((*intern)->mx_handler);
+ if ((*intern)->free_function_table) {
+ zend_ts_hash_destroy(&((*intern)->function_table));
+ }
+
pefree(*intern, TRUE);
}
@@ -439,7 +444,6 @@ ZEND_API ZEND_FUNCTION(rpc_load)
zval *object = getThis();
zval ***args, ***args_free;
zend_uint num_args = ZEND_NUM_ARGS();
- zend_class_entry overloaded_class_entry;
rpc_class_hash *class_hash;
rpc_internal *intern;
rpc_string hash_val, class_val;
@@ -474,7 +478,7 @@ ZEND_API ZEND_FUNCTION(rpc_load)
GET_ARGS_EX(num_args, args, args_free, 1);
/* if classname != integer */
- if ((zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 1 TSRMLS_CC, "l", &class_val.str) != SUCCESS) ||
+ if ((zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 1 TSRMLS_CC, "l", &class_val.len) != SUCCESS) ||
/* or we have no hash function */
!(RPC_HT(intern)->rpc_hash) ||
/* or integer hashing is not allowed */
@@ -495,12 +499,10 @@ ZEND_API ZEND_FUNCTION(rpc_load)
/* check if already hashed */
if ((class_hash = rpc_class_hash_find(&hash_val)) == NULL) {
- rpc_class_hash **class_hash_find;
-
ALLOC_CLASS_HASH(class_hash, intern->handlers);
/* do hashing */
- if (RPC_HT(intern)->rpc_hash(class_val, (rpc_string *)(class_hash), NULL, num_args, arg_types, CLASS) != SUCCESS) {
+ if (RPC_HT(intern)->rpc_hash(class_val, (rpc_string *) class_hash, NULL, num_args, arg_types, CLASS) != SUCCESS) {
/* TODO: exception */
ZVAL_NULL(object);
return;
@@ -508,39 +510,22 @@ ZEND_API ZEND_FUNCTION(rpc_load)
/* overload class entry */
RPC_HT(intern)->rpc_name(class_val, &class_val, NULL, CLASS);
- INIT_CLASS_ENTRY(overloaded_class_entry, NULL, NULL);
- overloaded_class_entry.name = class_val.str;
- overloaded_class_entry.name_length = class_val.len;
- class_hash->ce = zend_register_internal_class_ex(&overloaded_class_entry, intern->ce, NULL TSRMLS_CC);
- intern->ce = class_hash->ce;
- intern->function_table.hash = intern->ce->function_table;
+ OVERLOAD_RPC_CLASS(class_val, intern, class_hash);
/* register with non-hashed key
* also track all instaces in a llist for destruction later on, because there might be duplicate entries in
* the hashtable and we can't determine if a pointer references to an already freed element
*/
- tsrm_mutex_lock(classes.mx_writer);
- zend_ts_hash_add(&classes, hash_val.str, hash_val.len + 1, &class_hash, sizeof(rpc_class_hash *), (void **) &class_hash_find);
- zend_llist_add_element(&classes_list, class_hash_find);
- tsrm_mutex_unlock(classes.mx_writer);
-
- if (class_hash->name.str) {
- /* register string hashcode */
- zend_ts_hash_add(&classes, class_hash->name.str, class_hash->name.len + 1, &class_hash, sizeof(rpc_class_hash *), NULL);
- } else if (!class_hash->name.str && (RPC_HT(intern)->hash_type & HASH_AS_INT)) {
- /* register int hashcode */
- zend_ts_hash_index_update(&classes, class_hash->name.len, &class_hash, sizeof(rpc_class_hash *), NULL);
- }
+ REGISTER_RPC_CLASS(class_val, class_hash);
} else {
- intern->ce = class_hash->ce;
+ INIT_RPC_OBJECT(intern, class_hash);
}
FREE_SIGNATURE(hash_val, arg_types);
} else {
- /* overload class entry */
- INIT_CLASS_ENTRY(overloaded_class_entry, class_val.str, NULL);
- intern->ce = zend_register_internal_class_ex(&overloaded_class_entry, intern->ce, NULL TSRMLS_CC);
- intern->function_table.hash = intern->ce->function_table;
+ /* Copy the function table hash for this object, so that it is separated
+ * from the "global" table */
+ SEPARATE_RPC_CLASS(intern);
}
}
} else {
@@ -548,20 +533,18 @@ ZEND_API ZEND_FUNCTION(rpc_load)
if ((class_hash = rpc_class_hash_find(&hash_val)) == NULL) {
ALLOC_CLASS_HASH(class_hash, intern->handlers);
+ class_val.str = NULL;
class_hash->name.str = NULL;
class_hash->name.len = class_val.len;
/* overload class entry */
RPC_HT(intern)->rpc_name(class_val, &class_val, NULL, CLASS);
- INIT_CLASS_ENTRY(overloaded_class_entry, class_val.str, NULL);
- class_hash->ce = zend_register_internal_class_ex(&overloaded_class_entry, intern->ce, NULL TSRMLS_CC);
- intern->ce = class_hash->ce;
- intern->function_table.hash = intern->ce->function_table;
+ OVERLOAD_RPC_CLASS(class_val, intern, class_hash);
/* register int hashcode, we don't know more */
- zend_ts_hash_index_update(&classes, class_hash->name.len, &class_hash, sizeof(rpc_class_hash *), NULL);
+ REGISTER_RPC_CLASS(class_val, class_hash);
} else {
- intern->ce = class_hash->ce;
+ INIT_RPC_OBJECT(intern, class_hash);
}
}
@@ -795,6 +778,7 @@ ZEND_API zend_object_value rpc_objects_new(zend_class_entry *class_type TSRMLS_D
intern->ce = class_type;
intern->data = NULL;
+ intern->free_function_table = 0;
intern->function_table.reader = 0;
intern->function_table.mx_reader = tsrm_mutex_alloc();
intern->function_table.mx_writer = tsrm_mutex_alloc();
@@ -893,7 +877,7 @@ static rpc_class_hash *rpc_class_hash_find(rpc_string *name)
ZEND_API zval* _rpc_object_from_data(zval *z, rpc_handler_entry *handler, void *data, rpc_class_hash *class_hash)
{
rpc_internal *intern;
- rpc_string name = {NULL, 0};
+ rpc_string hash, name = {NULL, 0};
TSRMLS_FETCH();
if (z == NULL) {
@@ -908,27 +892,34 @@ ZEND_API zval* _rpc_object_from_data(zval *z, rpc_handler_entry *handler, void *
return NULL;
}
+ intern->ce = *(handler->ce);
intern->data = data;
- if (class_hash == NULL) {
- if (handler->handlers->rpc_name(name, &name, data, CLASS) == SUCCESS) {
- class_hash = rpc_class_hash_find(&name);
- } else {
- ALLOC_CLASS_HASH(class_hash, intern->handlers);
+ if ((handler->handlers->rpc_hash) &&
+ (handler->handlers->rpc_hash(name, &hash, data, 0, "", CLASS) == SUCCESS)) {
+ /* We are hashing, try to find an appropriate hash or create a new one */
+ if ((class_hash == NULL) &&
+ ((class_hash = rpc_class_hash_find(&hash)) == NULL)) {
+ ALLOC_CLASS_HASH(class_hash, intern->handlers);
- if (class_hash == NULL) {
- /* TODO: exception */
- return NULL;
+ class_hash->name = hash;
+
+ if (handler->handlers->rpc_name(hash, &name, data, CLASS) != SUCCESS) {
+ /* TODO exception */
+ }
+
+ OVERLOAD_RPC_CLASS(name, intern, class_hash);
+ REGISTER_RPC_CLASS(name, class_hash);
+ } else {
+ INIT_RPC_OBJECT(intern, class_hash);
}
-
- /* Copy the function table hash for this object, so that it is separated
- * from the "global" table */
- zend_ts_hash_init(&(intern->function_table), 0, NULL, NULL, TRUE);
- zend_hash_copy(&intern->function_table.hash, &((*(handler->ce))->function_table), NULL, NULL, 0);
- }
- }
- RPC_CLASS(intern) = class_hash;
+ RPC_CLASS(intern) = class_hash;
+ } else {
+ /* Copy the function table hash for this object, so that it is separated
+ * from the "global" table */
+ SEPARATE_RPC_CLASS(intern);
+ }
return z;
}