]> granicus.if.org Git - php/commitdiff
clean up source and improve hashing for implicitly
authorHarald Radi <phanto@php.net>
Tue, 11 Feb 2003 00:55:27 +0000 (00:55 +0000)
committerHarald Radi <phanto@php.net>
Tue, 11 Feb 2003 00:55:27 +0000 (00:55 +0000)
created objects (aka return values)

ext/rpc/handler.h
ext/rpc/rpc.c
ext/rpc/rpc.h

index a01598113b94b6a0994030c55220e44ec85c95d1..cbb868265cb8bc0aaee4f745ea0e209c76415a79 100644 (file)
@@ -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;
index 1eae43234ef90dd0e91bcd1545561b03edaf6913..6955d8b545c9544c7a6dd379f5122d1aa2187cf2 100644 (file)
@@ -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;
 }
index 7a90290a1681bc6eeb0affabe42867ad498532ec..07c760c36cb5f685b098edf3af0a87fd75e288df 100644 (file)
                        _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