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

Reply via email to