#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;
/* proxy data */
typedef struct _rpc_proxy {
- zend_uint refcount;
- zend_uint clonecount;
+ zend_uint dummy;
} rpc_proxy;
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);
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);
/**/
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,
NULL,
rpc_get_constructor,
rpc_get_class_entry,
- rpc_get_classname,
+ NULL,
rpc_compare
};
};
/* }}} */
+zend_class_entry rpc_class_entry;
+
static HashTable *handlers;
-static TsHashTable *instance;
-static TsHashTable *proxy;
static TsHashTable *classes;
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)
{
*/
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);
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);
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();
}
/* }}} */
-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;
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;
/* 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();
/* 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;
}
/* 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)
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 */
}
{
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 */
}
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);
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));
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);
}
{
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)
{
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;
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 */
}
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) {
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
*/
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);
{
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;
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;
* 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);
zval *object, *value;
char *property = NULL;
int property_len;
- rpc_internal **intern;
+ rpc_internal *intern;
/* get class entry */
GET_CLASS(ce);
}
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);
}
}
zval *object;
char *property = NULL;
int property_len;
- rpc_internal **intern;
+ rpc_internal *intern;
/* get class entry */
GET_CLASS(ce);
}
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;
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 */
}
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) {
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) {