summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarald Radi <phanto@php.net>2003-02-11 00:55:27 +0000
committerHarald Radi <phanto@php.net>2003-02-11 00:55:27 +0000
commitc7de5d15b73573d35599078a48f9a078f4c51d40 (patch)
tree0a783fb28cbc512025cd506aa50eac659f85f8dd
parentbe950d9c51449c6148667a660e001ae8d1f88442 (diff)
downloadphp-git-c7de5d15b73573d35599078a48f9a078f4c51d40.tar.gz
clean up source and improve hashing for implicitly
created objects (aka return values)
-rw-r--r--ext/rpc/handler.h1
-rw-r--r--ext/rpc/rpc.c93
-rw-r--r--ext/rpc/rpc.h36
3 files changed, 79 insertions, 51 deletions
diff --git a/ext/rpc/handler.h b/ext/rpc/handler.h
index a01598113b..cbb868265c 100644
--- a/ext/rpc/handler.h
+++ b/ext/rpc/handler.h
@@ -116,6 +116,7 @@ typedef struct _rpc_class_hash {
typedef struct _rpc_internal {
MUTEX_T mx_handler;
TsHashTable function_table;
+ zend_bool free_function_table;
rpc_object_handlers **handlers;
rpc_class_hash *hash;
zend_class_entry *ce;
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;
}
diff --git a/ext/rpc/rpc.h b/ext/rpc/rpc.h
index 7a90290a16..07c760c36c 100644
--- a/ext/rpc/rpc.h
+++ b/ext/rpc/rpc.h
@@ -134,4 +134,40 @@
_class_hash->handlers = _handlers; \
}
+#define INIT_RPC_OBJECT(__intern, __clh) \
+ (__intern)->ce = (__clh)->ce; \
+ (__intern)->function_table.hash = (__intern)->ce->function_table;
+
+#define OVERLOAD_RPC_CLASS(__name, __intern, __clh) { \
+ zend_class_entry overloaded_class_entry; \
+ INIT_CLASS_ENTRY(overloaded_class_entry, NULL, NULL); \
+ overloaded_class_entry.name = __name.str; \
+ overloaded_class_entry.name_length = (__name.str != NULL) ? __name.len : 0; \
+ (__clh)->ce = zend_register_internal_class_ex(&overloaded_class_entry, (__intern)->ce, NULL TSRMLS_CC); \
+ INIT_RPC_OBJECT(__intern, __clh); \
+ }
+
+#define SEPARATE_RPC_CLASS(__intern) \
+ (__intern)->free_function_table = 1; \
+ zend_ts_hash_init(&((__intern)->function_table), 0, NULL, NULL, TRUE); \
+ zend_hash_copy(&((__intern)->function_table.hash), &((__intern)->ce->function_table), NULL, NULL, 0);
+
+#define REGISTER_RPC_CLASS(__name, __class_hash) { \
+ rpc_class_hash **_tmp; \
+ if ((__name).str != NULL) { \
+ zend_ts_hash_add(&classes, (__name).str, (__name).len + 1, &(__class_hash), sizeof(rpc_class_hash *), (void **) &_tmp); \
+ } \
+ \
+ tsrm_mutex_lock(classes.mx_writer); \
+ zend_llist_add_element(&classes_list, _tmp); \
+ tsrm_mutex_unlock(classes.mx_writer); \
+ \
+ if ((__class_hash)->name.str) { \
+ zend_ts_hash_add(&classes, (__class_hash)->name.str, (__class_hash)->name.len + 1, &(__class_hash), sizeof(rpc_class_hash *), NULL); \
+ } else { \
+ zend_ts_hash_index_update(&classes, class_hash->name.len, &class_hash, sizeof(rpc_class_hash *), NULL); \
+ } \
+ }
+
+
#endif \ No newline at end of file