]> granicus.if.org Git - php/commitdiff
- using stas' abstraction now
authorHarald Radi <phanto@php.net>
Sun, 9 Jun 2002 14:51:41 +0000 (14:51 +0000)
committerHarald Radi <phanto@php.net>
Sun, 9 Jun 2002 14:51:41 +0000 (14:51 +0000)
- layer can add individual ini settings now
- classentries for the loaded rpc object are created dynamically now
  class hirarchy looks like: rpc<-[layer]<-[object]  (e.g. rpc<-com<-adodb),
  thus the whole class tree is reflected into php
- added user-functions to mark an object as a singleton and as poolable

#rest of the linuxtag work

ext/rpc/handler.h
ext/rpc/php_rpc.h
ext/rpc/rpc.c
ext/rpc/rpc.h
ext/rpc/rpc_proxy.c

index 04ec2c2f09eb1b59530aa7ee6fe2a59fb10492ae..81d4fbad8a6ebdbc6616e01cd0de42b6a332b719 100644 (file)
@@ -2,16 +2,18 @@
 #define HANDLER_H
 
 #include "php.h"
+#include "php_ini.h"
 
 #define RPC_HANDLER(layer)                             {#layer, layer##_handler_init, &layer##_object_handlers,        \
                                                                                &layer##_class_entry, layer##_function_entry,                           \
-                                                                               layer##_method_entry}
+                                                                               layer##_method_entry, layer##_ini_entry}
 
 #define RPC_DECLARE_HANDLER(layer)             void layer##_handler_init();                                    \
                                                                                rpc_object_handlers layer##_object_handlers;    \
                                                                                zend_class_entry layer##_class_entry;                   \
                                                                                function_entry layer##_function_entry[];                \
-                                                                               function_entry layer##_method_entry[];
+                                                                               function_entry layer##_method_entry[];                  \
+                                                                               zend_ini_entry layer##_ini_entry[];
 
 #define RPC_INIT_FUNCTION(layer)               void layer##_handler_init()
 
 
 #define RPC_REGISTER_HANDLERS_END()                            };
 
+#define RPC_INI_START(layer)                   zend_ini_entry layer##_ini_entry[] = {
+#define RPC_INI_END()                                  { 0, 0, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, NULL } };
   
-#define RPC_FUNCTION_ENTRY_START(layer)        function_entry layer##_function_entry[] = {             \
-                                                                                       ZEND_FALIAS(layer##_load, rpc_load, NULL)       \
-                                                                                       ZEND_FALIAS(layer##_call, rpc_call, NULL)       \
-                                                                                       ZEND_FALIAS(layer##_get, rpc_get, NULL)         \
-                                                                                       ZEND_FALIAS(layer##_set, rpc_set, NULL)
+#define RPC_FUNCTION_ENTRY_START(layer)        function_entry layer##_function_entry[] = {                             \
+                                                                                       ZEND_FALIAS(layer##_load, rpc_load, NULL)                       \
+                                                                                       ZEND_FALIAS(layer##_call, rpc_call, NULL)                       \
+                                                                                       ZEND_FALIAS(layer##_get, rpc_get, NULL)                         \
+                                                                                       ZEND_FALIAS(layer##_set, rpc_get, NULL)                         \
+                                                                                       ZEND_FALIAS(layer##_singleton, rpc_singleton, NULL)     \
+                                                                                       ZEND_FALIAS(layer##_poolable, rpc_poolable, NULL)
 
 #define RPC_FUNCTION_ENTRY_END()                       {NULL, NULL, NULL}                                                      \
                                                                                };
 #define RPC_METHOD_ENTRY_END()                         {NULL, NULL, NULL}                                                      \
                                                                                };
 
-#define POOL           TRUE
-#define DONT_POOL      FALSE
-
 #define DONT_HASH      0
 #define HASH_AS_INT    1
 #define HASH_AS_STRING 2
 #define HASH_WITH_SIGNATURE 4
-#define HASH_AS_INT_WITH_SIGNATURE (HASH_AS_INT + HASH_WITH_SIGNATURE)
-#define HASH_AS_STRING_WITH_SIGNATURE (HASH_AS_STRING + HASH_WITH_SIGNATURE)
+#define HASH_AS_INT_WITH_SIGNATURE (HASH_AS_INT & HASH_WITH_SIGNATURE)
+#define HASH_AS_STRING_WITH_SIGNATURE (HASH_AS_STRING & HASH_WITH_SIGNATURE)
 
 #define CLASS 0
 #define METHOD 1
 #define PROPERTY 2
 
 
+/* string */
+typedef struct _rpc_string {
+       char *str;
+       zend_uint len;
+} rpc_string;
+
 /* rpc handler that have to be implemented by a 
  * specific rpc layer
  */
 typedef struct _rpc_object_handlers {
-       const zend_bool pool_instances;
+       const zend_bool poolable;
        const zend_uint hash_type;
-       int (*rpc_hash)(char *name, zend_uint name_len, char **hash, zend_uint *hash_len, int num_args, char *arg_types, int type);
-       int (*rpc_ctor)(char *class_name, zend_uint class_name_len, void **data, int num_args, zval **args[]);
+       int (*rpc_hash)(rpc_string name, rpc_string *hash, int num_args, char *arg_types, int type);
+       int (*rpc_name)(rpc_string hash, rpc_string *name, int type);
+       int (*rpc_ctor)(rpc_string class_name, void **data, int num_args, zval **args[]);
        int (*rpc_dtor)(void **data);
-       int (*rpc_call)(char *method_name, zend_uint method_name_len, void **data, zval **return_value, int num_args, zval **args[]);
-       int (*rpc_get)(char *property_name, zend_uint property_name_len, zval *return_value, void **data);
-       int (*rpc_set)(char *property_name, zend_uint property_name_len, zval *value, void **data);
+       int (*rpc_call)(rpc_string method_name, void **data, zval **return_value, int num_args, zval **args[]);
+       int (*rpc_get)(rpc_string property_name, zval *return_value, void **data);
+       int (*rpc_set)(rpc_string property_name, zval *value, void **data);
        int (*rpc_compare)(void **data1, void **data2);
-       int (*rpc_get_classname)(char **class_name, zend_uint *class_name_length, void **data);
-       int (*rpc_has_property)(char *property_name, zend_uint property_name_length, void **data);
-       int (*rpc_unset_property)(char *property_name, zend_uint property_name_length, void **data);
+       int (*rpc_has_property)(rpc_string property_name, void **data);
+       int (*rpc_unset_property)(rpc_string property_name, void **data);
        int (*rpc_get_properties)(HashTable **properties, void **data);
 } rpc_object_handlers;
 
 /* handler entry */
 typedef struct _rpc_handler_entry {
-       char                                            *name;
+       char                                    *name;
        void (*rpc_handler_init)();
-       rpc_object_handlers     *handlers;
+       rpc_object_handlers             *handlers;
        zend_class_entry                *ce;
        function_entry                  *functions;
        function_entry                  *methods;
+       zend_ini_entry                  *ini;
 } rpc_handler_entry;
 
-/* string */
-typedef struct _rpc_string {
-       char *str;
-       zend_uint len;
-} rpc_string;
-
 /* class/method/function hash */
 typedef struct _rpc_class_hash {
        rpc_string name; /* must be first entry */
        TsHashTable methods;
        TsHashTable properties;
+       zend_class_entry                *ce;
 } rpc_class_hash;
 
 /* internal data */
 typedef struct _rpc_internal {
-       char                                            *class_name;
-       zend_uint                               class_name_len;
+       zend_bool                               poolable;
+       zend_bool                               singleton;
        zend_class_entry                *ce;
-       rpc_object_handlers     **handlers;
-       void                                            *data;
-       zend_uint                               refcount;
-       zend_uint                               clonecount;
-       zend_bool                               pool_instances;
+       rpc_object_handlers             **handlers;
+       void                                    *data;
        rpc_class_hash                  *hash;
        TsHashTable                             function_table;
        MUTEX_T                                 mx_handler;
@@ -109,8 +111,7 @@ typedef struct _rpc_internal {
 
 /* proxy data */
 typedef struct _rpc_proxy {
-       zend_uint                               refcount;
-       zend_uint                               clonecount;
+       zend_uint                               dummy;
 } rpc_proxy;
 
 
index be95b209409efe3fdbe347a17194a0b9de9ce0b5..32074ee70d114918c1718e0aff3364fddde344de 100644 (file)
@@ -18,15 +18,19 @@ extern zend_module_entry rpc_module_entry;
 
 ZEND_MINIT_FUNCTION(rpc);
 ZEND_MSHUTDOWN_FUNCTION(rpc);
+ZEND_RINIT_FUNCTION(rpc);
+ZEND_RSHUTDOWN_FUNCTION(rpc);
 ZEND_MINFO_FUNCTION(rpc);
 
 ZEND_FUNCTION(rpc_load);
 ZEND_FUNCTION(rpc_call);
 ZEND_FUNCTION(rpc_set);
 ZEND_FUNCTION(rpc_get);
+ZEND_FUNCTION(rpc_singleton);
+ZEND_FUNCTION(rpc_poolable);
 
 ZEND_BEGIN_MODULE_GLOBALS(rpc)
-       int dummy;
+       TsHashTable *proxy;
 ZEND_END_MODULE_GLOBALS(rpc)
 
 #ifdef ZTS
index d0fc90a49cc99a136e502aa6a81aa46b01aa2c3f..04a5f1f02c69fd1efb4e9d583844c14d8c025fd4 100644 (file)
 ZEND_DECLARE_MODULE_GLOBALS(rpc)
 
 static void rpc_globals_ctor(zend_rpc_globals * TSRMLS_DC);
-static void rpc_instance_dtor(void *);
-static void rpc_proxy_dtor(void *pDest);
 static void rpc_class_dtor(void *);
 static void rpc_string_dtor(void *);
 static void rpc_export_functions(char *, zend_class_entry *, function_entry[] TSRMLS_DC);
-static zend_object_value rpc_create_object(zend_class_entry * TSRMLS_DC);
+
+static zend_object_value rpc_objects_new(zend_class_entry * TSRMLS_DC);
+static void rpc_objects_delete(void *object, zend_object_handle handle TSRMLS_DC);
 
 /* object handler */
-static void rpc_add_ref(zval * TSRMLS_DC);
-static void rpc_del_ref(zval * TSRMLS_DC);
-static void rpc_delete(zval * TSRMLS_DC);
-static zend_object_value rpc_clone(zval * TSRMLS_DC);
 static zval* rpc_read(zval *, zval *, int  TSRMLS_DC);
 static void rpc_write(zval *, zval *, zval * TSRMLS_DC);
 static zval** rpc_get_property(zval *, zval * TSRMLS_DC);
@@ -35,8 +31,7 @@ static void rpc_unset_property(zval *, zval * TSRMLS_DC);
 static HashTable* rpc_get_properties(zval * TSRMLS_DC);
 static union _zend_function* rpc_get_method(zval *, char *, int TSRMLS_DC);
 static union _zend_function* rpc_get_constructor(zval * TSRMLS_DC);
-static zend_class_entry** rpc_get_class_entry(zval *object TSRMLS_DC);
-static int rpc_get_classname(zval *, char **, zend_uint *, int  TSRMLS_DC);
+static zend_class_entry* rpc_get_class_entry(zval *object TSRMLS_DC);
 static int rpc_compare(zval *, zval * TSRMLS_DC);
 /**/
 
@@ -48,16 +43,16 @@ static void rpc_internal_set(rpc_internal *, char *, zend_uint, zval *);
 extern zend_object_handlers rpc_proxy_handlers;
 
 static zend_object_handlers rpc_handlers = {
-       rpc_add_ref,
-       rpc_del_ref,
-       rpc_delete,
-       rpc_clone,
+       ZEND_OBJECTS_STORE_HANDLERS,
+
        rpc_read,
        rpc_write,
        rpc_get_property,
        NULL,
        rpc_get,
        rpc_set,
+       NULL,
+       NULL,
        rpc_has_property,
        rpc_unset_property,
        rpc_get_properties,
@@ -65,7 +60,7 @@ static zend_object_handlers rpc_handlers = {
        NULL,
        rpc_get_constructor,
        rpc_get_class_entry,
-       rpc_get_classname,
+       NULL,
        rpc_compare
 };
 
@@ -92,9 +87,9 @@ zend_module_entry rpc_module_entry = {
 };
 /* }}} */
 
+zend_class_entry rpc_class_entry;
+
 static HashTable *handlers;
-static TsHashTable *instance;
-static TsHashTable *proxy;
 static TsHashTable *classes;
 static zend_llist *classes_list;
 
@@ -102,12 +97,8 @@ static zend_llist *classes_list;
 ZEND_GET_MODULE(rpc);
 #endif
 
-/* {{{ PHP_INI
- */
-PHP_INI_BEGIN()
-/* TODO: add module specific ini settings here */
-PHP_INI_END()
-/* }}} */
+ZEND_INI_BEGIN()
+ZEND_INI_END()
 
 static void rpc_globals_ctor(zend_rpc_globals *rpc_globals TSRMLS_DC)
 {
@@ -117,15 +108,17 @@ static void rpc_globals_ctor(zend_rpc_globals *rpc_globals TSRMLS_DC)
  */
 ZEND_MINIT_FUNCTION(rpc)
 {
+       zend_class_entry *rpc_entry;
+
+       /* rpc base class entry */
+       INIT_CLASS_ENTRY(rpc_class_entry, "rpc", NULL);
+       rpc_entry = zend_register_internal_class(&rpc_class_entry TSRMLS_CC);
+
        handlers = (HashTable *) pemalloc(sizeof(HashTable), TRUE);
-       instance = (TsHashTable *) pemalloc(sizeof(TsHashTable), TRUE);
-       proxy = (TsHashTable *) pemalloc(sizeof(TsHashTable), TRUE);
        classes = (TsHashTable *) pemalloc(sizeof(TsHashTable), TRUE);
        classes_list = (zend_llist *) pemalloc(sizeof(zend_llist), TRUE);
 
        zend_hash_init(handlers, 0, NULL, NULL, TRUE);  
-       zend_ts_hash_init(instance, 0, NULL, rpc_instance_dtor, TRUE);
-       zend_ts_hash_init(proxy, 0, NULL, rpc_proxy_dtor, TRUE);
        zend_ts_hash_init(classes, 0, NULL, NULL, TRUE);
        zend_llist_init(classes_list, sizeof(rpc_class_hash **), rpc_class_dtor, TRUE);
 
@@ -133,21 +126,19 @@ ZEND_MINIT_FUNCTION(rpc)
                HANDLER.rpc_handler_init();
                
                /* create a class entry for every rpc handler */
-               INIT_OVERLOADED_CLASS_ENTRY((*(HANDLER.ce)),
-                                                                       HANDLER.name,
-                                                                       HANDLER.methods,
-                                                                       NULL,
-                                                                       NULL,
-                                                                       NULL);
+               INIT_CLASS_ENTRY((*(HANDLER.ce)),
+                                                       HANDLER.name,
+                                                       HANDLER.methods);
 
-               HANDLER.ce->create_object = rpc_create_object;
+               HANDLER.ce->create_object = rpc_objects_new;
 
                /* load all available rpc handler into a hash */
                zend_hash_add(handlers, HANDLER.name, strlen(HANDLER.name) + 1, &(HANDLER.handlers), sizeof(rpc_object_handlers *), NULL);
 
                /* register classes and functions */
-               zend_register_internal_class(HANDLER.ce TSRMLS_CC);
+               zend_register_internal_class_ex(HANDLER.ce, rpc_entry, NULL TSRMLS_CC);
                zend_register_functions(HANDLER.functions, NULL, MODULE_PERSISTENT TSRMLS_CC);
+               zend_register_ini_entries(HANDLER.ini, module_number TSRMLS_CC);
        }
 
        ZEND_INIT_MODULE_GLOBALS(rpc, rpc_globals_ctor, NULL);
@@ -162,16 +153,12 @@ ZEND_MINIT_FUNCTION(rpc)
 ZEND_MSHUTDOWN_FUNCTION(rpc)
 {
        /* destroy instances first */
-       zend_ts_hash_destroy(instance);
-       zend_ts_hash_destroy(proxy);
        zend_ts_hash_destroy(classes);
 
        zend_llist_destroy(classes_list);
        zend_hash_destroy(handlers);
 
        pefree(handlers, TRUE);
-       pefree(instance, TRUE);
-       pefree(proxy, TRUE);
        pefree(classes, TRUE);
 
        UNREGISTER_INI_ENTRIES();
@@ -191,30 +178,6 @@ ZEND_MINFO_FUNCTION(rpc)
 }
 /* }}} */
 
-static void rpc_instance_dtor(void *pDest)
-{
-       rpc_internal **intern;
-       
-       intern = (rpc_internal **) pDest;
-       
-       (*(*intern)->handlers)->rpc_dtor(&((*intern)->data));
-
-       tsrm_mutex_free((*intern)->function_table.mx_reader);
-       tsrm_mutex_free((*intern)->function_table.mx_writer);
-       tsrm_mutex_free((*intern)->mx_handler);
-
-       pefree(*intern, TRUE);
-}
-
-static void rpc_proxy_dtor(void *pDest)
-{
-       rpc_proxy **proxy_intern;
-       
-       proxy_intern = (rpc_proxy **) pDest;
-       
-       pefree(*proxy_intern, TRUE);
-}
-
 static void rpc_class_dtor(void *pDest)
 {
        rpc_class_hash **hash;
@@ -238,7 +201,7 @@ static void rpc_string_dtor(void *pDest)
        pefree(*string, TRUE);
 }
 
-static zend_object_value rpc_create_object(zend_class_entry *class_type TSRMLS_DC)
+static zend_object_value rpc_objects_new(zend_class_entry *class_type TSRMLS_DC)
 {
        zend_object_value *zov;
        rpc_internal *intern;
@@ -250,13 +213,10 @@ static zend_object_value rpc_create_object(zend_class_entry *class_type TSRMLS_D
        /* set up the internal representation of our rpc instance */
        intern = (rpc_internal *) pemalloc(sizeof(rpc_internal), TRUE);
 
-       intern->class_name = NULL;
-       intern->class_name_len = 0;
        intern->ce = class_type;
-       intern->refcount = 1;
-       intern->clonecount = 1;
        intern->data = NULL;
-       intern->pool_instances = 0;
+       intern->singleton = FALSE;
+       intern->poolable = FALSE;
        intern->function_table.hash = intern->ce->function_table;
        intern->function_table.reader = 0;
        intern->function_table.mx_reader = tsrm_mutex_alloc();
@@ -267,15 +227,7 @@ static zend_object_value rpc_create_object(zend_class_entry *class_type TSRMLS_D
                /* TODO: exception */
        }
 
-       /* store the instance in a hash and set the key as handle, thus
-        * we can find it later easily
-        */
-       tsrm_mutex_lock(instance->mx_writer);
-       {
-               zov->handle = zend_hash_next_free_element(&(instance->hash));
-               zend_ts_hash_next_index_insert(instance, &intern, sizeof(rpc_internal *), NULL);
-       }
-       tsrm_mutex_unlock(instance->mx_writer);
+       zov->handle = zend_objects_store_put(intern, rpc_objects_delete, NULL TSRMLS_CC);
 
        return *zov;
 }
@@ -295,69 +247,26 @@ static zend_object_value rpc_create_proxy(TSRMLS_D)
        /* store the instance in a hash and set the key as handle, thus
         * we can find it later easily
         */
-       tsrm_mutex_lock(proxy->mx_writer);
+/*     tsrm_mutex_lock(proxy->mx_writer);
        {
                zov->handle = zend_hash_next_free_element(&(proxy->hash));
                zend_ts_hash_next_index_insert(proxy, &proxy_intern, sizeof(rpc_proxy *), NULL);
        }
        tsrm_mutex_unlock(proxy->mx_writer);
-
+*/
        return *zov;
 }
 
 /* object handler */
 
-static void rpc_add_ref(zval *object TSRMLS_DC)
-{
-       GET_INTERNAL(intern);
-       RPC_ADDREF(intern);
-}
-
-static void rpc_del_ref(zval *object TSRMLS_DC)
+static void rpc_objects_delete(void *object, zend_object_handle handle TSRMLS_DC)
 {
-       rpc_internal **intern;
-
-       if (GET_INTERNAL_EX(intern, object) == SUCCESS) {
-               if (RPC_REFCOUNT(intern) > 0) {
-                       RPC_DELREF(intern);
-               }
-
-               if (RPC_REFCOUNT(intern) == 0) {
-                       zend_ts_hash_index_del(instance, Z_OBJ_HANDLE(*object));
-               }
-       }
-}
-
-static void rpc_delete(zval *object TSRMLS_DC)
-{
-       rpc_internal **intern;
+       rpc_internal *intern = (rpc_internal *) object;
        
-       if (GET_INTERNAL_EX(intern, object) == SUCCESS) {
-               if (RPC_CLONECOUNT(intern) > 0) {
-                       RPC_DELCLONE(intern);
-               }
-
-               if (RPC_CLONECOUNT(intern) == 0) {
-                       zend_ts_hash_index_del(instance, Z_OBJ_HANDLE_P(object));
+       if (intern->poolable) {
                }
-       }
-}
-
-static zend_object_value rpc_clone(zval *object TSRMLS_DC)
-{
-       GET_INTERNAL(intern);
-
-       /* cloning the underlaying resource is neither possible nor would it
-        * make sense, therfore we return the old zend_object_value and increase
-        * the clone count to not loose the clone when the original object gets
-        * deleted.
-        */
-       RPC_ADDCLONE(intern);
-       
-       /* also increase the refcounter as a clone is just another reference */
-       RPC_ADDREF(intern);
-
-       return object->value.obj;
+       /* TODO: pool */
+       pefree(intern, TRUE);
 }
 
 static zval* rpc_read(zval *object, zval *member, int type TSRMLS_DC)
@@ -372,10 +281,10 @@ static zval* rpc_read(zval *object, zval *member, int type TSRMLS_DC)
        ZVAL_DELREF(return_value);
        ZVAL_NULL(return_value);
 
-       if ((*intern)->hash && Z_TYPE_P(member) == IS_LONG) {
-               rpc_internal_get(*intern, NULL, Z_LVAL_P(member), return_value);
+       if (intern->hash && Z_TYPE_P(member) == IS_LONG) {
+               rpc_internal_get(intern, NULL, Z_LVAL_P(member), return_value);
        } else if (Z_TYPE_P(member) == IS_STRING) {
-               rpc_internal_get(*intern, Z_STRVAL_P(member), Z_STRLEN_P(member), return_value);
+               rpc_internal_get(intern, Z_STRVAL_P(member), Z_STRLEN_P(member), return_value);
        } else {
                /* TODO: exception here */
        }
@@ -387,10 +296,10 @@ static void rpc_write(zval *object, zval *member, zval *value TSRMLS_DC)
 {
        GET_INTERNAL(intern);
 
-       if ((*intern)->hash && Z_TYPE_P(member) == IS_LONG) {
-               rpc_internal_set(*intern, NULL, Z_LVAL_P(member), value);
+       if (intern->hash && Z_TYPE_P(member) == IS_LONG) {
+               rpc_internal_set(intern, NULL, Z_LVAL_P(member), value);
        } else if (Z_TYPE_P(member) == IS_STRING) {
-               rpc_internal_set(*intern, Z_STRVAL_P(member), Z_STRLEN_P(member), value);
+               rpc_internal_set(intern, Z_STRVAL_P(member), Z_STRLEN_P(member), value);
        } else {
                /* TODO: exception here */
        }
@@ -403,7 +312,6 @@ static zval** rpc_get_property(zval *object, zval *member TSRMLS_DC)
 
        return_value = emalloc(sizeof(zval *));
        MAKE_STD_ZVAL(*return_value);
-//     ZVAL_DELREF(*return_value);
        Z_TYPE_P(object) = IS_OBJECT;
        (*return_value)->value.obj = rpc_create_proxy(TSRMLS_C);
 
@@ -448,7 +356,7 @@ static union _zend_function* rpc_get_method(zval *object, char *method, int meth
        zend_function *function;
        GET_INTERNAL(intern);
 
-       if (zend_ts_hash_find(&((*intern)->function_table), method, method_len + 1, &function) != SUCCESS) {
+       if (zend_ts_hash_find(&(intern->function_table), method, method_len + 1, &function) != SUCCESS) {
                zend_internal_function *zif;
 
                zif = (zend_internal_function *) emalloc(sizeof(zend_internal_function));
@@ -459,7 +367,7 @@ static union _zend_function* rpc_get_method(zval *object, char *method, int meth
                zif->type = ZEND_INTERNAL_FUNCTION;
 
                /* add new method to the method table */
-               zend_ts_hash_add(&((*intern)->function_table), method, method_len + 1, zif, sizeof(zend_function), &function);
+               zend_ts_hash_add(&(intern->function_table), method, method_len + 1, zif, sizeof(zend_function), &function);
                efree(zif);
        }
 
@@ -470,39 +378,31 @@ static union _zend_function* rpc_get_constructor(zval *object TSRMLS_DC)
 {
        zend_function *rpc_ctor;
        GET_INTERNAL(intern);
-       
-       if (zend_ts_hash_find(&((*intern)->function_table), (*intern)->ce->name, (*intern)->ce->name_length + 1, &rpc_ctor) != SUCCESS) {
+
+       if (zend_ts_hash_find(&(intern->function_table), intern->ce->name, intern->ce->name_length + 1, &rpc_ctor) != SUCCESS) {
                zend_internal_function *zif;
 
                zif = (zend_internal_function *) emalloc(sizeof(zend_internal_function));
 
                zif->type = ZEND_INTERNAL_FUNCTION;
-               zif->function_name = (*intern)->ce->name;
-               zif->scope = (*intern)->ce;
+               zif->function_name = intern->ce->name;
+               zif->scope = intern->ce;
                zif->arg_types = NULL;
                zif->handler = ZEND_FN(rpc_load);
 
                /* add new constructor to the method table */
-               zend_ts_hash_add(&((*intern)->function_table), (*intern)->ce->name, (*intern)->ce->name_length + 1, zif, sizeof(zend_function), &rpc_ctor);
+               zend_ts_hash_add(&(intern->function_table), intern->ce->name, intern->ce->name_length + 1, zif, sizeof(zend_function), &rpc_ctor);
                efree(zif);
        }
 
        return rpc_ctor;
 }
 
-static zend_class_entry** rpc_get_class_entry(zval *object TSRMLS_DC)
+static zend_class_entry* rpc_get_class_entry(zval *object TSRMLS_DC)
 {
        GET_INTERNAL(intern);
 
-       return &((*intern)->ce);
-}
-
-static int rpc_get_classname(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC)
-{
-//     GET_INTERNAL(intern);
-
-       /* FIXME */
-       return FAILURE;
+       return intern->ce;
 }
 
 static int rpc_compare(zval *object1, zval *object2 TSRMLS_DC)
@@ -518,11 +418,12 @@ ZEND_FUNCTION(rpc_load)
 {
        zval *object = getThis();
        zval ***args, ***args_free;
-       zend_uint num_args = ZEND_NUM_ARGS(); 
+       zend_uint num_args = ZEND_NUM_ARGS();
+       zend_class_entry overloaded_class_entry;
        rpc_class_hash *class_hash;
        rpc_class_hash **class_hash_find = NULL;
-       rpc_internal **intern;
-       rpc_string hash_val;
+       rpc_internal *intern;
+       rpc_string hash_val, class_val;
        int retval, append = 0;
        char *arg_types;
 
@@ -541,7 +442,7 @@ ZEND_FUNCTION(rpc_load)
                Z_TYPE_P(object) = IS_OBJECT;
 
                /* create a new object */
-               object->value.obj = rpc_create_object(*ce TSRMLS_CC);
+               object->value.obj = rpc_objects_new(*ce TSRMLS_CC);
 
                /* now everything is set up the same way as if we were called as a constructor */
        }
@@ -554,22 +455,22 @@ 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", &((*intern)->class_name_len)) != SUCCESS) ||
+       if ((zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 1 TSRMLS_CC, "l", &class_val.str) != SUCCESS) ||
                /* or we have no hash function */
-               !((*(*intern)->handlers)->rpc_hash) ||
+               !(RPC_HT(intern)->rpc_hash) ||
                /* or integer hashing is not allowed */
-               !((*(*intern)->handlers)->hash_type & HASH_AS_INT)) {
+               !(RPC_HT(intern)->hash_type & HASH_AS_INT)) {
 
                /* else check for string - classname */
-               if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 1 TSRMLS_CC, "s", &((*intern)->class_name), &((*intern)->class_name_len)) != SUCCESS) {
+               if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 1 TSRMLS_CC, "s", &class_val.str, &class_val.len) != SUCCESS) {
                        /* none of the two possibilities */
                        /* TODO: exception */
                        php_error(E_WARNING, "wrong arguments for %s()", get_active_function_name(TSRMLS_C));
                } else {
                        /* hash classname if hashing function exists */
-                       if ((*(*intern)->handlers)->rpc_hash) {
+                       if (RPC_HT(intern)->rpc_hash) {
 
-                               GET_CTOR_SIGNATURE(intern, hash_val, num_args, arg_types);
+                               GET_SIGNATURE(intern, class_val.str, class_val.len, hash_val, num_args, arg_types);
 
                                /* check if already hashed */   
                                if (zend_ts_hash_find(classes, hash_val.str, hash_val.len + 1, (void **) &class_hash_find) != SUCCESS) {
@@ -579,14 +480,20 @@ ZEND_FUNCTION(rpc_load)
                                        zend_ts_hash_init(&(class_hash->methods), 0, NULL, rpc_string_dtor, TRUE);
                                        zend_ts_hash_init(&(class_hash->properties), 0, NULL, rpc_string_dtor, TRUE);
 
-
                                        /* do hashing */
-                                       if ((*(*intern)->handlers)->rpc_hash((*intern)->class_name, (*intern)->class_name_len, &(class_hash->name.str),
-                                                                                                                &(class_hash->name.len), num_args, arg_types, CLASS) != SUCCESS) {
+                                       if (RPC_HT(intern)->rpc_hash(class_val, (rpc_string *)(class_hash), num_args, arg_types, CLASS) != SUCCESS) {
                                                /* TODO: exception */
                                        }
 
-                                       /* register with non-hashed key 
+                                       /* overload class entry */
+                                       RPC_HT(intern)->rpc_name(class_val, &class_val, 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;
+
+                                       /* 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
                                         */
@@ -598,49 +505,61 @@ ZEND_FUNCTION(rpc_load)
                                        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 && ((*(*intern)->handlers)->hash_type & HASH_AS_INT)) {
+                                       } 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);
                                        }
                                } else {
                                        class_hash = *class_hash_find;
+                                       intern->ce = class_hash->ce;
                                }
 
                                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);
                        }
                }
        } else {
                /* integer classname (hashcode) */
-               if (zend_ts_hash_index_find(classes, (*intern)->class_name_len, (void**) &class_hash_find) != SUCCESS) {
+               if (zend_ts_hash_index_find(classes, class_val.len, (void**) &class_hash_find) != SUCCESS) {
                        class_hash = pemalloc(sizeof(rpc_class_hash), TRUE);
 
                        /* set up the cache */
                        class_hash->name.str = NULL;
-                       class_hash->name.len = (*intern)->class_name_len;
+                       class_hash->name.len = class_val.len;
 
                        zend_ts_hash_init(&(class_hash->methods), 0, NULL, rpc_string_dtor, TRUE);
                        zend_ts_hash_init(&(class_hash->properties), 0, NULL, rpc_string_dtor, TRUE);
 
+                       /* overload class entry */
+                       RPC_HT(intern)->rpc_name(class_val, &class_val, 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;
+
                        /* 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);
                } else {
                        class_hash = *class_hash_find;
+                       intern->ce = class_hash->ce;
                }
        }
        
        /* if hash function available */
-       if ((*(*intern)->handlers)->rpc_hash) {
+       if (RPC_HT(intern)->rpc_hash) {
                /* assign cache structure */
-               (*intern)->hash = class_hash;
+               intern->hash = class_hash;
                
                /* call the rpc ctor */
-               retval = (*(*intern)->handlers)->rpc_ctor(class_hash->name.str, class_hash->name.len, &((*intern)->data), num_args, args);
+               retval = RPC_HT(intern)->rpc_ctor(*(rpc_string *)(class_hash), &(intern->data), num_args, args);
        } else {
                /* disable caching from now on */
-               (*intern)->hash = NULL;
+               intern->hash = NULL;
 
                /* call the rpc ctor */
-               retval = (*(*intern)->handlers)->rpc_ctor((*intern)->class_name, (*intern)->class_name_len, &((*intern)->data), num_args, args);
+               retval = RPC_HT(intern)->rpc_ctor(class_val, &(intern->data), num_args, args);
        }
 
        efree(args_free);
@@ -654,7 +573,7 @@ ZEND_FUNCTION(rpc_call)
 {
        zval *object = getThis();
        zval ***args, ***args_free;
-       zend_uint num_args = ZEND_NUM_ARGS(); 
+       zend_uint num_args = ZEND_NUM_ARGS();
        char *hash = NULL, *arg_types;
        int hash_len, retval, strip = 0;
 
@@ -690,23 +609,23 @@ ZEND_FUNCTION(rpc_call)
                method_hash->str = hash;
                method_hash->len = hash_len;
                
-               if ((*intern)->hash) {
+               if (intern->hash) {
                        /* cache method table lookups */
                
-                       if (!hash && !((*(*intern)->handlers)->hash_type & HASH_AS_INT)) {
+                       if (!hash && !(RPC_HT(intern)->hash_type & HASH_AS_INT)) {
                                /* TODO: exception */
                        } else if(hash) {
                                /* string passed */
                                GET_METHOD_SIGNATURE(intern, method_hash, hash_val, num_args, arg_types);
 
                                /* check if already hashed */   
-                               if (zend_ts_hash_find(&((*intern)->hash->methods), hash_val.str, hash_val.len + 1, (void **) &method_hash_find) != SUCCESS) {
-                                       if ((*(*intern)->handlers)->rpc_hash(hash, hash_len, &(method_hash->str), &(method_hash->len), num_args, arg_types, METHOD) != SUCCESS) {
+                               if (zend_ts_hash_find(&(intern->hash->methods), hash_val.str, hash_val.len + 1, (void **) &method_hash_find) != SUCCESS) {
+                                       if (RPC_HT(intern)->rpc_hash(*method_hash, method_hash, num_args, arg_types, METHOD) != SUCCESS) {
                                                /* TODO: exception */
                                        }
 
                                        /* register with non-hashed key */
-                                       zend_ts_hash_add(&((*intern)->hash->methods), hash_val.str, hash_val.len + 1, &method_hash, sizeof(rpc_string *), NULL);
+                                       zend_ts_hash_add(&(intern->hash->methods), hash_val.str, hash_val.len + 1, &method_hash, sizeof(rpc_string *), NULL);
                                } else {
                                        pefree(method_hash, TRUE);
                                        method_hash = *method_hash_find;
@@ -720,9 +639,9 @@ ZEND_FUNCTION(rpc_call)
                 * considering possible thread implementations in future php versions
                 * and srm it is better to do concurrency checks
                 */
-               tsrm_mutex_lock((*intern)->mx_handler);
-               retval = (*(*intern)->handlers)->rpc_call(method_hash->str, method_hash->len, &((*intern)->data), &return_value, num_args, args);
-               tsrm_mutex_unlock((*intern)->mx_handler);
+               tsrm_mutex_lock(intern->mx_handler);
+               retval = RPC_HT(intern)->rpc_call(*method_hash, &(intern->data), &return_value, num_args, args);
+               tsrm_mutex_unlock(intern->mx_handler);
        }
 
        efree(args_free);
@@ -737,7 +656,7 @@ ZEND_FUNCTION(rpc_set)
        zval *object, *value;
        char *property = NULL;
        int property_len;
-       rpc_internal **intern;
+       rpc_internal *intern;
        /* get class entry */
        GET_CLASS(ce);
 
@@ -750,10 +669,10 @@ ZEND_FUNCTION(rpc_set)
        }
 
        GET_INTERNAL_EX(intern, object);
-       if (!property && !(*intern)->hash) {
+       if (!property && !intern->hash) {
                /* TODO: exception here */
        } else {
-               rpc_internal_set(*intern, property, property_len, value);
+               rpc_internal_set(intern, property, property_len, value);
        }
 }
 
@@ -762,7 +681,7 @@ ZEND_FUNCTION(rpc_get)
        zval *object;
        char *property = NULL;
        int property_len;
-       rpc_internal **intern;
+       rpc_internal *intern;
        /* get class entry */
        GET_CLASS(ce);
 
@@ -775,13 +694,49 @@ ZEND_FUNCTION(rpc_get)
        }
 
        GET_INTERNAL_EX(intern, object);
-       if (!property && !(*intern)->hash) {
+       if (!property && !intern->hash) {
                /* TODO: exception here */
        } else {
-               rpc_internal_get(*intern, property, property_len, return_value);
+               rpc_internal_get(intern, property, property_len, return_value);
        }
 }
 
+ZEND_FUNCTION(rpc_singleton)
+{
+       zval *object;
+       rpc_internal *intern;
+       /* get class entry */
+       GET_CLASS(ce);
+
+       zend_parse_parameters(1 TSRMLS_CC, "O", &object, *ce);
+
+       GET_INTERNAL_EX(intern, object);
+
+       if (!intern->singleton) {
+               intern->singleton = TRUE;
+               /* TODO: add to instance list */
+       }
+}
+
+ZEND_FUNCTION(rpc_poolable)
+{
+       zval *object;
+       rpc_internal *intern;
+       /* get class entry */
+       GET_CLASS(ce);
+
+       zend_parse_parameters(1 TSRMLS_CC, "O", &object, *ce);
+
+       GET_INTERNAL_EX(intern, object);
+
+
+       if (RPC_HT(intern)->poolable == TRUE) {
+               intern->poolable = TRUE;
+       }
+}
+
+/*******************/
+
 static void rpc_internal_get(rpc_internal *intern, char *property, zend_uint property_len, zval *return_value)
 {
        int retval;
@@ -796,12 +751,12 @@ static void rpc_internal_get(rpc_internal *intern, char *property, zend_uint pro
        if (intern->hash) {
                /* cache method table lookups */
        
-               if (!property && !((*intern->handlers)->hash_type & HASH_AS_INT)) {
+               if (!property && !(RPC_HT(intern)->hash_type & HASH_AS_INT)) {
                        /* TODO: exception */
                } else if(property) {
                        /* check if already hashed */   
                        if (zend_ts_hash_find(&(intern->hash->properties), property, property_len + 1, (void **) &property_hash_find) != SUCCESS) {
-                               if ((*intern->handlers)->rpc_hash(property, property_len, &(property_hash->str), &(property_hash->len), 0, NULL, PROPERTY) != SUCCESS) {
+                               if (RPC_HT(intern)->rpc_hash(*property_hash, property_hash, 0, NULL, PROPERTY) != SUCCESS) {
                                        /* TODO: exception */
                                }
 
@@ -816,7 +771,7 @@ static void rpc_internal_get(rpc_internal *intern, char *property, zend_uint pro
 
 
        tsrm_mutex_lock(intern->mx_handler);
-       retval = (*intern->handlers)->rpc_get(property_hash->str, property_hash->len, return_value, intern->data);
+       retval = RPC_HT(intern)->rpc_get(*property_hash, return_value, intern->data);
        tsrm_mutex_unlock(intern->mx_handler);
 
        if (retval != SUCCESS) {
@@ -827,9 +782,13 @@ static void rpc_internal_get(rpc_internal *intern, char *property, zend_uint pro
 static void rpc_internal_set(rpc_internal *intern, char *property, zend_uint property_len, zval *value)
 {
        int retval;
+       rpc_string property_name;
+
+       property_name.str = property;
+       property_name.len = property_len;
 
        tsrm_mutex_lock(intern->mx_handler);
-       retval = (*intern->handlers)->rpc_set(property, property_len, value, intern->data);
+       retval = RPC_HT(intern)->rpc_set(property_name, value, intern->data);
        tsrm_mutex_unlock(intern->mx_handler);
 
        if (retval != SUCCESS) {
index 43f6bd8ae3a7f5502ce50d038e05cf10d374d23d..092707fa13c5d6109babd6236a64c82de3bbe336 100644 (file)
@@ -5,12 +5,14 @@
 #define HANDLER handler_entries[__handler_counter]
 #define HANDLER_COUNT (sizeof(handler_entries) / sizeof(rpc_handler_entry))
 
-#define GET_INTERNAL(intern)   rpc_internal **intern;                                                          \
+#define RPC_HT(intern) (*(intern->handlers))
+
+#define GET_INTERNAL(intern)   rpc_internal *intern;                                                           \
                                                                if (GET_INTERNAL_EX(intern, object) != SUCCESS) {       \
                                                                        /* TODO: exception */                                                   \
                                                                }
 
-#define GET_INTERNAL_EX(intern, object)        zend_ts_hash_index_find(instance, object->value.obj.handle, (void **) &intern)
+#define GET_INTERNAL_EX(intern, object)        (((intern = zend_object_store_get_object(object TSRMLS_CC)) == NULL) ? FAILURE : SUCCESS)
 
 #define GET_CLASS(ce)  char *key;                                                                                                                                                              \
                                                int key_len;                                                                                                                                                    \
                                                        /* TODO: exception */                                                                                   \
                                                }
 
-#define GET_CTOR_SIGNATURE(intern, hash_val, num_args, arg_types)                                                                                                      \
-                       GET_SIGNATURE(intern, (*intern)->class_name, (*intern)->class_name_len, hash_val, num_args, arg_types)
-
 #define GET_METHOD_SIGNATURE(intern, method, hash_val, num_args, arg_types)                                                                                    \
                        GET_SIGNATURE(intern, method->str, method->len, hash_val, num_args, arg_types)
 
 #define GET_SIGNATURE(intern, name, name_len, hash_val, num_args, arg_types)                                                                           \
                                                hash_val.len = name_len;                                                                                                                                        \
                                                                                                                                                                                                                                        \
-                                               if ((*(*intern)->handlers)->hash_type & HASH_WITH_SIGNATURE) {                                                          \
+                                               if ((*intern->handlers)->hash_type & HASH_WITH_SIGNATURE) {                                                             \
                                                        zend_uint _signature_counter;                                                                                                                   \
                                                                                                                                                                                                                                        \
                                                        arg_types = (char *) emalloc(sizeof(char) * (num_args + 1));                                                    \
                                                efree(arg_types);                                                                                                                                                       \
                                                efree(hash_val.str);
 
-
-
-#define RPC_REFCOUNT(intern) ((*intern)->refcount)
-#define RPC_ADDREF(intern) (++RPC_REFCOUNT(intern))
-#define RPC_DELREF(intern) (--RPC_REFCOUNT(intern))
-
-#define RPC_CLONECOUNT(intern) ((*intern)->clonecount)
-#define RPC_ADDCLONE(intern) (++RPC_CLONECOUNT(intern))
-#define RPC_DELCLONE(intern) (--RPC_CLONECOUNT(intern))
-
 static int __handler_counter;
 
 #endif
\ No newline at end of file
index ef1cabe0edfbd7b60627e9f8fe80a9b317390e19..e36303a3fc02409e0c0870b6269d6b68f2cf2128 100644 (file)
@@ -18,7 +18,7 @@ static void rpc_proxy_unset_property(zval *, zval * TSRMLS_DC);
 static HashTable* rpc_proxy_get_properties(zval * TSRMLS_DC);
 static union _zend_function* rpc_proxy_get_method(zval *, char *, int TSRMLS_DC);
 static union _zend_function* rpc_proxy_get_constructor(zval * TSRMLS_DC);
-static zend_class_entry** rpc_proxy_get_class_entry(zval *object TSRMLS_DC);
+static zend_class_entry* rpc_proxy_get_class_entry(zval *object TSRMLS_DC);
 static int rpc_proxy_get_classname(zval *, char **, zend_uint *, int  TSRMLS_DC);
 static int rpc_proxy_compare(zval *, zval * TSRMLS_DC);
 /**/
@@ -34,6 +34,8 @@ zend_object_handlers rpc_proxy_handlers = {
        NULL,
        rpc_proxy_get,
        rpc_proxy_set,
+       NULL,
+       NULL,
        rpc_proxy_has_property,
        rpc_proxy_unset_property,
        rpc_proxy_get_properties,
@@ -111,7 +113,7 @@ static union _zend_function* rpc_proxy_get_constructor(zval *object TSRMLS_DC)
        return NULL;
 }
 
-static zend_class_entry** rpc_proxy_get_class_entry(zval *object TSRMLS_DC)
+static zend_class_entry* rpc_proxy_get_class_entry(zval *object TSRMLS_DC)
 {
        return NULL;
 }