phanto Mon Feb 10 19:55:27 2003 EDT Modified files: /php4/ext/rpc handler.h rpc.c rpc.h Log: clean up source and improve hashing for implicitly created objects (aka return values)
Index: php4/ext/rpc/handler.h diff -u php4/ext/rpc/handler.h:1.16 php4/ext/rpc/handler.h:1.17 --- php4/ext/rpc/handler.h:1.16 Mon Feb 10 15:59:10 2003 +++ php4/ext/rpc/handler.h Mon Feb 10 19:55:26 2003 @@ -116,6 +116,7 @@ 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; Index: php4/ext/rpc/rpc.c diff -u php4/ext/rpc/rpc.c:1.22 php4/ext/rpc/rpc.c:1.23 --- php4/ext/rpc/rpc.c:1.22 Mon Feb 10 15:59:10 2003 +++ php4/ext/rpc/rpc.c Mon Feb 10 19:55:26 2003 @@ -229,6 +229,11 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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; } Index: php4/ext/rpc/rpc.h diff -u php4/ext/rpc/rpc.h:1.13 php4/ext/rpc/rpc.h:1.14 --- php4/ext/rpc/rpc.h:1.13 Mon Feb 10 15:59:10 2003 +++ php4/ext/rpc/rpc.h Mon Feb 10 19:55:26 2003 @@ -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
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php