mirror of
https://github.com/php/php-src.git
synced 2025-08-21 01:45:16 +02:00
added lookup caching and now make use of the new thread
safe hashtables (not in cvs right now)
This commit is contained in:
parent
68f63a012f
commit
a85ea38eac
6 changed files with 214 additions and 272 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
/* protos */
|
/* protos */
|
||||||
static int com_hash(char *name, zend_uint name_len, char **hash, zend_uint *hash_len, int type);
|
static int com_hash(char *name, zend_uint name_len, char **hash, zend_uint *hash_len, int type);
|
||||||
static int com_ctor(char *class_name, zend_uint class_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
|
static int com_ctor(char *class_name, zend_uint class_name_len, void **data, int num_args, zval **args[]);
|
||||||
static int com_dtor(void **data);
|
static int com_dtor(void **data);
|
||||||
static int com_call(char *method_name, zend_uint method_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
|
static int com_call(char *method_name, zend_uint method_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
|
||||||
static int com_get(char *property_name, zend_uint property_name_len, zval *return_value, void **data);
|
static int com_get(char *property_name, zend_uint property_name_len, zval *return_value, void **data);
|
||||||
|
@ -15,9 +15,10 @@ static int com_get_properties(HashTable **properties, void **data);
|
||||||
|
|
||||||
|
|
||||||
/* register rpc callback function */
|
/* register rpc callback function */
|
||||||
RPC_REGISTER_HANDLERS_START(com, DONT_POOL)
|
RPC_REGISTER_HANDLERS_START(com)
|
||||||
|
POOL,
|
||||||
|
HASH_AS_INT,
|
||||||
com_hash,
|
com_hash,
|
||||||
HASH_AS_STRING,
|
|
||||||
com_ctor,
|
com_ctor,
|
||||||
com_dtor,
|
com_dtor,
|
||||||
com_call,
|
com_call,
|
||||||
|
@ -52,10 +53,13 @@ RPC_INIT_FUNCTION(com)
|
||||||
|
|
||||||
static int com_hash(char *name, zend_uint name_len, char **hash, zend_uint *hash_len, int type)
|
static int com_hash(char *name, zend_uint name_len, char **hash, zend_uint *hash_len, int type)
|
||||||
{
|
{
|
||||||
|
*hash = strdup(name);
|
||||||
|
*hash_len = name_len;
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int com_ctor(char *class_name, zend_uint class_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS)
|
static int com_ctor(char *class_name, zend_uint class_name_len, void **data, int num_args, zval **args[])
|
||||||
{
|
{
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,9 @@
|
||||||
|
|
||||||
#define RPC_HANDLER(layer) {#layer, layer##_handler_init, &layer##_object_handlers, \
|
#define RPC_HANDLER(layer) {#layer, layer##_handler_init, &layer##_object_handlers, \
|
||||||
&layer##_class_entry, layer##_function_entry, \
|
&layer##_class_entry, layer##_function_entry, \
|
||||||
layer##_method_entry, &layer##_pool}
|
layer##_method_entry}
|
||||||
|
|
||||||
#define RPC_DECLARE_HANDLER(layer) void layer##_handler_init(); \
|
#define RPC_DECLARE_HANDLER(layer) void layer##_handler_init(); \
|
||||||
const int layer##_pool; \
|
|
||||||
rpc_object_handlers layer##_object_handlers; \
|
rpc_object_handlers layer##_object_handlers; \
|
||||||
zend_class_entry layer##_class_entry; \
|
zend_class_entry layer##_class_entry; \
|
||||||
function_entry layer##_function_entry[]; \
|
function_entry layer##_function_entry[]; \
|
||||||
|
@ -16,8 +15,7 @@
|
||||||
|
|
||||||
#define RPC_INIT_FUNCTION(layer) void layer##_handler_init()
|
#define RPC_INIT_FUNCTION(layer) void layer##_handler_init()
|
||||||
|
|
||||||
#define RPC_REGISTER_HANDLERS_START(layer, p) zend_class_entry layer##_class_entry; \
|
#define RPC_REGISTER_HANDLERS_START(layer) zend_class_entry layer##_class_entry; \
|
||||||
const int layer##_pool = p; \
|
|
||||||
rpc_object_handlers layer##_object_handlers = {
|
rpc_object_handlers layer##_object_handlers = {
|
||||||
|
|
||||||
#define RPC_REGISTER_HANDLERS_END() };
|
#define RPC_REGISTER_HANDLERS_END() };
|
||||||
|
@ -43,17 +41,19 @@
|
||||||
#define HASH_AS_STRING FALSE
|
#define HASH_AS_STRING FALSE
|
||||||
#define DONT_HASH FALSE
|
#define DONT_HASH FALSE
|
||||||
|
|
||||||
#define METHOD 0
|
#define CLASS 0
|
||||||
#define PROPERTY 1
|
#define METHOD 1
|
||||||
|
#define PROPERTY 2
|
||||||
|
|
||||||
|
|
||||||
/* rpc handler that have to be implemented by a
|
/* rpc handler that have to be implemented by a
|
||||||
* specific rpc layer
|
* specific rpc layer
|
||||||
*/
|
*/
|
||||||
typedef struct _rpc_object_handlers {
|
typedef struct _rpc_object_handlers {
|
||||||
|
const zend_bool pool_instances;
|
||||||
|
const int hash_type;
|
||||||
int (*rpc_hash)(char *name, zend_uint name_len, char **hash, zend_uint *hash_len, int type);
|
int (*rpc_hash)(char *name, zend_uint name_len, char **hash, zend_uint *hash_len, int type);
|
||||||
int hash_type;
|
int (*rpc_ctor)(char *class_name, zend_uint class_name_len, void **data, int num_args, zval **args[]);
|
||||||
int (*rpc_ctor)(char *class_name, zend_uint class_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
|
|
||||||
int (*rpc_dtor)(void **data);
|
int (*rpc_dtor)(void **data);
|
||||||
int (*rpc_call)(char *method_name, zend_uint method_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
|
int (*rpc_call)(char *method_name, zend_uint method_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
|
||||||
int (*rpc_get)(char *property_name, zend_uint property_name_len, zval *return_value, void **data);
|
int (*rpc_get)(char *property_name, zend_uint property_name_len, zval *return_value, void **data);
|
||||||
|
@ -73,17 +73,34 @@ typedef struct _rpc_handler_entry {
|
||||||
zend_class_entry *ce;
|
zend_class_entry *ce;
|
||||||
function_entry *functions;
|
function_entry *functions;
|
||||||
function_entry *methods;
|
function_entry *methods;
|
||||||
const int *pool_instances;
|
|
||||||
} rpc_handler_entry;
|
} 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 */
|
||||||
|
WormHashTable methods;
|
||||||
|
WormHashTable properties;
|
||||||
|
} rpc_class_hash;
|
||||||
|
|
||||||
/* internal data */
|
/* internal data */
|
||||||
typedef struct _rpc_internal {
|
typedef struct _rpc_internal {
|
||||||
|
char *class_name;
|
||||||
|
zend_uint class_name_len;
|
||||||
zend_class_entry *ce;
|
zend_class_entry *ce;
|
||||||
rpc_object_handlers **handlers;
|
rpc_object_handlers **handlers;
|
||||||
void **data;
|
void *data;
|
||||||
unsigned refcount;
|
zend_uint refcount;
|
||||||
unsigned clonecount;
|
zend_uint clonecount;
|
||||||
int pool_instances;
|
zend_bool pool_instances;
|
||||||
|
rpc_class_hash *hash;
|
||||||
|
MUTEX_T mx_handler;
|
||||||
} rpc_internal;
|
} rpc_internal;
|
||||||
|
|
||||||
|
|
||||||
#endif /* HANDLER_H */
|
#endif /* HANDLER_H */
|
209
ext/rpc/rpc.c
209
ext/rpc/rpc.c
|
@ -14,29 +14,31 @@ ZEND_DECLARE_MODULE_GLOBALS(rpc)
|
||||||
|
|
||||||
static int rpc_global_startup(void);
|
static int rpc_global_startup(void);
|
||||||
static int rpc_global_shutdown(void);
|
static int rpc_global_shutdown(void);
|
||||||
static void rpc_globals_ctor(zend_rpc_globals *rpc_globals TSRMLS_DC);
|
static void rpc_globals_ctor(zend_rpc_globals * TSRMLS_DC);
|
||||||
static void rpc_instance_dtor(void *pDest);
|
static void rpc_instance_dtor(void *);
|
||||||
static void rpc_export_functions(char *name, zend_class_entry *ce, function_entry functions[] TSRMLS_DC);
|
static void rpc_class_dtor(void *);
|
||||||
static zend_object_value rpc_create_object(zend_class_entry *class_type TSRMLS_DC);
|
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);
|
||||||
|
|
||||||
/* object handler */
|
/* object handler */
|
||||||
static void rpc_add_ref(zval *object TSRMLS_DC);
|
static void rpc_add_ref(zval * TSRMLS_DC);
|
||||||
static void rpc_del_ref(zval *object TSRMLS_DC);
|
static void rpc_del_ref(zval * TSRMLS_DC);
|
||||||
static void rpc_delete(zval *object TSRMLS_DC);
|
static void rpc_delete(zval * TSRMLS_DC);
|
||||||
static zend_object_value rpc_clone(zval *object TSRMLS_DC);
|
static zend_object_value rpc_clone(zval * TSRMLS_DC);
|
||||||
static zval* rpc_read(zval *object, zval *member, int type TSRMLS_DC);
|
static zval* rpc_read(zval *, zval *, int TSRMLS_DC);
|
||||||
static void rpc_write(zval *object, zval *member, zval *value TSRMLS_DC);
|
static void rpc_write(zval *, zval *, zval * TSRMLS_DC);
|
||||||
static zval** rpc_get_property(zval *object, zval *member TSRMLS_DC);
|
static zval** rpc_get_property(zval *, zval * TSRMLS_DC);
|
||||||
static zval* rpc_get(zval *property TSRMLS_DC);
|
static zval* rpc_get(zval * TSRMLS_DC);
|
||||||
static void rpc_set(zval **property, zval *value TSRMLS_DC);
|
static void rpc_set(zval **, zval * TSRMLS_DC);
|
||||||
static int rpc_has_property(zval *object, zval *member, int check_empty TSRMLS_DC);
|
static int rpc_has_property(zval *, zval *, int TSRMLS_DC);
|
||||||
static void rpc_unset_property(zval *object, zval *member TSRMLS_DC);
|
static void rpc_unset_property(zval *, zval * TSRMLS_DC);
|
||||||
static HashTable* rpc_get_properties(zval *object TSRMLS_DC);
|
static HashTable* rpc_get_properties(zval * TSRMLS_DC);
|
||||||
static union _zend_function* rpc_get_method(zval *object, char *method, int method_len TSRMLS_DC);
|
static union _zend_function* rpc_get_method(zval *, char *, int TSRMLS_DC);
|
||||||
static int rpc_call(char *method, INTERNAL_FUNCTION_PARAMETERS);
|
static int rpc_call(char *, INTERNAL_FUNCTION_PARAMETERS);
|
||||||
static union _zend_function* rpc_get_constructor(zval *object TSRMLS_DC);
|
static union _zend_function* rpc_get_constructor(zval * TSRMLS_DC);
|
||||||
static int rpc_get_classname(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC);
|
static int rpc_get_classname(zval *, char **, zend_uint *, int TSRMLS_DC);
|
||||||
static int rpc_compare(zval *object1, zval *object2 TSRMLS_DC);
|
static int rpc_compare(zval *, zval * TSRMLS_DC);
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
static zend_object_handlers rpc_handlers = {
|
static zend_object_handlers rpc_handlers = {
|
||||||
|
@ -83,10 +85,10 @@ zend_module_entry rpc_module_entry = {
|
||||||
};
|
};
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static HashTable *instance;
|
|
||||||
static HashTable *handlers;
|
static HashTable *handlers;
|
||||||
|
static WormHashTable *instance;
|
||||||
|
static WormHashTable *classes;
|
||||||
|
|
||||||
static MUTEX_T mx_instance;
|
|
||||||
static unsigned long thread_count = 0;
|
static unsigned long thread_count = 0;
|
||||||
|
|
||||||
#ifdef COMPILE_DL_RPC
|
#ifdef COMPILE_DL_RPC
|
||||||
|
@ -105,13 +107,13 @@ PHP_INI_END()
|
||||||
*/
|
*/
|
||||||
static int rpc_global_startup(void)
|
static int rpc_global_startup(void)
|
||||||
{
|
{
|
||||||
mx_instance = tsrm_mutex_alloc();
|
|
||||||
|
|
||||||
handlers = (HashTable *) pemalloc(sizeof(HashTable), TRUE);
|
handlers = (HashTable *) pemalloc(sizeof(HashTable), TRUE);
|
||||||
instance = (HashTable *) pemalloc(sizeof(HashTable), TRUE);
|
instance = (WormHashTable *) pemalloc(sizeof(WormHashTable), TRUE);
|
||||||
|
classes = (WormHashTable *) pemalloc(sizeof(WormHashTable), TRUE);
|
||||||
|
|
||||||
zend_hash_init(handlers, 0, NULL, NULL, TRUE);
|
zend_hash_init(handlers, 0, NULL, NULL, TRUE);
|
||||||
zend_hash_init(instance, 0, NULL, rpc_instance_dtor, TRUE);
|
zend_worm_hash_init(instance, 0, NULL, rpc_instance_dtor, TRUE);
|
||||||
|
zend_worm_hash_init(classes, 0, NULL, rpc_class_dtor, TRUE);
|
||||||
|
|
||||||
FOREACH_HANDLER {
|
FOREACH_HANDLER {
|
||||||
HANDLER.rpc_handler_init();
|
HANDLER.rpc_handler_init();
|
||||||
|
@ -136,10 +138,13 @@ static int rpc_global_startup(void)
|
||||||
/* same as above for shutdown */
|
/* same as above for shutdown */
|
||||||
static int rpc_global_shutdown(void)
|
static int rpc_global_shutdown(void)
|
||||||
{
|
{
|
||||||
tsrm_mutex_free(mx_instance);
|
|
||||||
|
|
||||||
zend_hash_destroy(handlers);
|
zend_hash_destroy(handlers);
|
||||||
zend_hash_destroy(instance);
|
zend_worm_hash_destroy(instance);
|
||||||
|
zend_worm_hash_destroy(classes);
|
||||||
|
|
||||||
|
pefree(handlers, TRUE);
|
||||||
|
pefree(instance, TRUE);
|
||||||
|
pefree(classes, TRUE);
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -207,6 +212,29 @@ static void rpc_instance_dtor(void *pDest)
|
||||||
pefree(*intern, TRUE);
|
pefree(*intern, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rpc_class_dtor(void *pDest)
|
||||||
|
{
|
||||||
|
rpc_class_hash **hash;
|
||||||
|
|
||||||
|
hash = (rpc_class_hash **) pDest;
|
||||||
|
|
||||||
|
zend_worm_hash_destroy(&((*hash)->methods));
|
||||||
|
zend_worm_hash_destroy(&((*hash)->properties));
|
||||||
|
|
||||||
|
free((*hash)->name.str);
|
||||||
|
pefree(*hash, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_string_dtor(void *pDest)
|
||||||
|
{
|
||||||
|
rpc_string **string;
|
||||||
|
|
||||||
|
string = (rpc_string **) pDest;
|
||||||
|
|
||||||
|
free((*string)->str);
|
||||||
|
pefree(*string, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
static zend_object_value rpc_create_object(zend_class_entry *class_type TSRMLS_DC)
|
static zend_object_value rpc_create_object(zend_class_entry *class_type TSRMLS_DC)
|
||||||
{
|
{
|
||||||
zend_object_value *zov;
|
zend_object_value *zov;
|
||||||
|
@ -218,10 +246,16 @@ static zend_object_value rpc_create_object(zend_class_entry *class_type TSRMLS_D
|
||||||
|
|
||||||
/* set up the internal representation of our rpc instance */
|
/* set up the internal representation of our rpc instance */
|
||||||
intern = (rpc_internal *) pemalloc(sizeof(rpc_internal), TRUE);
|
intern = (rpc_internal *) pemalloc(sizeof(rpc_internal), TRUE);
|
||||||
|
|
||||||
|
intern->class_name = NULL;
|
||||||
|
intern->class_name_len = 0;
|
||||||
intern->ce = class_type;
|
intern->ce = class_type;
|
||||||
intern->refcount = 1;
|
intern->refcount = 1;
|
||||||
intern->clonecount = 1;
|
intern->clonecount = 1;
|
||||||
intern->data = NULL;
|
intern->data = NULL;
|
||||||
|
intern->pool_instances = 0;
|
||||||
|
intern->mx_handler = tsrm_mutex_alloc();
|
||||||
|
|
||||||
if (zend_hash_find(handlers, class_type->name, class_type->name_length + 1, (void **) &(intern->handlers)) == FAILURE) {
|
if (zend_hash_find(handlers, class_type->name, class_type->name_length + 1, (void **) &(intern->handlers)) == FAILURE) {
|
||||||
/* TODO: exception */
|
/* TODO: exception */
|
||||||
}
|
}
|
||||||
|
@ -229,12 +263,12 @@ static zend_object_value rpc_create_object(zend_class_entry *class_type TSRMLS_D
|
||||||
/* store the instance in a hash and set the key as handle, thus
|
/* store the instance in a hash and set the key as handle, thus
|
||||||
* we can find it later easily
|
* we can find it later easily
|
||||||
*/
|
*/
|
||||||
tsrm_mutex_lock(mx_instance);
|
tsrm_mutex_lock(instance->mx_writer);
|
||||||
{
|
{
|
||||||
zov->handle = instance->nNextFreeElement;
|
zov->handle = zend_hash_next_free_element(&(instance->hash));
|
||||||
zend_hash_next_index_insert(instance, &intern, sizeof(rpc_internal *), NULL);
|
zend_worm_hash_next_index_insert(instance, &intern, sizeof(rpc_internal *), NULL);
|
||||||
}
|
}
|
||||||
tsrm_mutex_unlock(mx_instance);
|
tsrm_mutex_unlock(instance->mx_writer);
|
||||||
|
|
||||||
return *zov;
|
return *zov;
|
||||||
}
|
}
|
||||||
|
@ -257,7 +291,7 @@ static void rpc_del_ref(zval *object TSRMLS_DC)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RPC_REFCOUNT(intern) == 0) {
|
if (RPC_REFCOUNT(intern) == 0) {
|
||||||
zend_hash_index_del(instance, Z_OBJ_HANDLE(*object));
|
zend_worm_hash_index_del(instance, Z_OBJ_HANDLE(*object));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,7 +306,7 @@ static void rpc_delete(zval *object TSRMLS_DC)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RPC_CLONECOUNT(intern) == 0) {
|
if (RPC_CLONECOUNT(intern) == 0) {
|
||||||
zend_hash_index_del(instance, Z_OBJ_HANDLE_P(object));
|
zend_worm_hash_index_del(instance, Z_OBJ_HANDLE_P(object));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,16 +354,13 @@ static zval** rpc_get_property(zval *object, zval *member TSRMLS_DC)
|
||||||
|
|
||||||
static zval* rpc_get(zval *property TSRMLS_DC)
|
static zval* rpc_get(zval *property TSRMLS_DC)
|
||||||
{
|
{
|
||||||
// GET_INTERNAL(intern);
|
/* not yet implemented */
|
||||||
|
|
||||||
/* FIXME */
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rpc_set(zval **property, zval *value TSRMLS_DC)
|
static void rpc_set(zval **property, zval *value TSRMLS_DC)
|
||||||
{
|
{
|
||||||
// GET_INTERNAL(intern);
|
/* not yet implemented */
|
||||||
/* FIXME */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rpc_has_property(zval *object, zval *member, int check_empty TSRMLS_DC)
|
static int rpc_has_property(zval *object, zval *member, int check_empty TSRMLS_DC)
|
||||||
|
@ -386,6 +417,7 @@ static union _zend_function* rpc_get_constructor(zval *object TSRMLS_DC)
|
||||||
rpc_ctor = (zend_internal_function *) emalloc(sizeof(zend_internal_function));
|
rpc_ctor = (zend_internal_function *) emalloc(sizeof(zend_internal_function));
|
||||||
|
|
||||||
rpc_ctor->type = ZEND_INTERNAL_FUNCTION;
|
rpc_ctor->type = ZEND_INTERNAL_FUNCTION;
|
||||||
|
rpc_ctor->function_name = (*intern)->ce->name;
|
||||||
rpc_ctor->scope = (*intern)->ce;
|
rpc_ctor->scope = (*intern)->ce;
|
||||||
rpc_ctor->arg_types = NULL;
|
rpc_ctor->arg_types = NULL;
|
||||||
rpc_ctor->handler = ZEND_FN(rpc_load);
|
rpc_ctor->handler = ZEND_FN(rpc_load);
|
||||||
|
@ -413,6 +445,10 @@ static int rpc_compare(zval *object1, zval *object2 TSRMLS_DC)
|
||||||
ZEND_FUNCTION(rpc_load)
|
ZEND_FUNCTION(rpc_load)
|
||||||
{
|
{
|
||||||
zval *object = getThis();
|
zval *object = getThis();
|
||||||
|
zval ***args;
|
||||||
|
zend_uint num_args = ZEND_NUM_ARGS();
|
||||||
|
rpc_class_hash *class_hash;
|
||||||
|
rpc_class_hash **class_hash_find = NULL;
|
||||||
rpc_internal **intern;
|
rpc_internal **intern;
|
||||||
|
|
||||||
/* check if we were called as a constructor or as a function */
|
/* check if we were called as a constructor or as a function */
|
||||||
|
@ -456,9 +492,96 @@ ZEND_FUNCTION(rpc_load)
|
||||||
/* TODO: exception */
|
/* TODO: exception */
|
||||||
}
|
}
|
||||||
|
|
||||||
// (*intern)->handlers.rpc_ctor(
|
/* if classname != integer */
|
||||||
|
if ((zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 2 TSRMLS_CC, "l", &((*intern)->class_name_len)) == FAILURE) ||
|
||||||
|
/* or we have no hash function */
|
||||||
|
!((*(*intern)->handlers)->rpc_hash) ||
|
||||||
|
/* or integer hashing is not allowed */
|
||||||
|
((*(*intern)->handlers)->hash_type != HASH_AS_INT)) {
|
||||||
|
|
||||||
/* FIXME */
|
/* else check for string - classname */
|
||||||
|
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 2 TSRMLS_CC, "s", &((*intern)->class_name), &((*intern)->class_name_len)) == FAILURE) {
|
||||||
|
/* none of the two possibilities */
|
||||||
|
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) {
|
||||||
|
|
||||||
|
/* check if already hashed */
|
||||||
|
if (zend_worm_hash_find(classes, (*intern)->class_name, (*intern)->class_name_len + 1, (void **) &class_hash_find) == FAILURE) {
|
||||||
|
class_hash = pemalloc(sizeof(rpc_class_hash), TRUE);
|
||||||
|
|
||||||
|
/* set up the cache */
|
||||||
|
zend_worm_hash_init(&(class_hash->methods), 0, NULL, rpc_string_dtor, TRUE);
|
||||||
|
zend_worm_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), CLASS) == FAILURE) {
|
||||||
|
/* TODO: exception */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* register with non-hashed key */
|
||||||
|
zend_worm_hash_add(classes, (*intern)->class_name, (*intern)->class_name_len + 1, &class_hash, sizeof(rpc_class_hash *), NULL);
|
||||||
|
|
||||||
|
if (class_hash->name.str) {
|
||||||
|
/* register string hashcode */
|
||||||
|
zend_worm_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)) {
|
||||||
|
/* register int hashcode */
|
||||||
|
zend_worm_hash_index_update(classes, class_hash->name.len, &class_hash, sizeof(rpc_class_hash *), NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
class_hash = *class_hash_find;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* integer classname (hashcode) */
|
||||||
|
if (zend_worm_hash_index_find(classes, (*intern)->class_name_len, (void**) &class_hash_find) == FAILURE) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
zend_worm_hash_init(&(class_hash->methods), 0, NULL, rpc_string_dtor, TRUE);
|
||||||
|
zend_worm_hash_init(&(class_hash->properties), 0, NULL, rpc_string_dtor, TRUE);
|
||||||
|
|
||||||
|
/* register int hashcode, we don't know more */
|
||||||
|
zend_worm_hash_index_update(classes, class_hash->name.len, &class_hash, sizeof(rpc_class_hash *), NULL);
|
||||||
|
} else {
|
||||||
|
class_hash = *class_hash_find;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fetch further parameters */
|
||||||
|
args = (zval ***) emalloc(sizeof(zval **) * num_args);
|
||||||
|
|
||||||
|
if (zend_get_parameters_array_ex(num_args, args) == FAILURE) {
|
||||||
|
/* TODO: exception */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strip away the first two parameters */
|
||||||
|
num_args -= 2;
|
||||||
|
args = (num_args > 0) ? &args[2] : NULL;
|
||||||
|
|
||||||
|
/* if hash function available */
|
||||||
|
if ((*(*intern)->handlers)->rpc_hash) {
|
||||||
|
/* assign cache structure */
|
||||||
|
(*intern)->hash = class_hash;
|
||||||
|
|
||||||
|
/* call the rpc ctor */
|
||||||
|
(*(*intern)->handlers)->rpc_ctor(class_hash->name.str, class_hash->name.len, &((*intern)->data), num_args, args);
|
||||||
|
} else {
|
||||||
|
/* disable caching from now on */
|
||||||
|
(*intern)->hash = NULL;
|
||||||
|
|
||||||
|
/* call the rpc ctor */
|
||||||
|
(*(*intern)->handlers)->rpc_ctor((*intern)->class_name, (*intern)->class_name_len, &((*intern)->data), num_args, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* efree hash_find stuff ? */
|
||||||
}
|
}
|
||||||
|
|
||||||
ZEND_FUNCTION(rpc_call)
|
ZEND_FUNCTION(rpc_call)
|
||||||
|
|
203
ext/rpc/rpc.dsp
203
ext/rpc/rpc.dsp
|
@ -1,203 +0,0 @@
|
||||||
# Microsoft Developer Studio Project File - Name="rpc" - Package Owner=<4>
|
|
||||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
|
||||||
# ** DO NOT EDIT **
|
|
||||||
|
|
||||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
|
||||||
|
|
||||||
CFG=rpc - Win32 Debug_TS
|
|
||||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
|
||||||
!MESSAGE use the Export Makefile command and run
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "rpc.mak".
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE You can specify a configuration when running NMAKE
|
|
||||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "rpc.mak" CFG="rpc - Win32 Debug_TS"
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE Possible choices for configuration are:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE "rpc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
|
||||||
!MESSAGE "rpc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
|
||||||
!MESSAGE "rpc - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
|
|
||||||
!MESSAGE "rpc - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
|
|
||||||
!MESSAGE
|
|
||||||
|
|
||||||
# Begin Project
|
|
||||||
# PROP AllowPerConfigDependencies 0
|
|
||||||
# PROP Scc_ProjName ""
|
|
||||||
# PROP Scc_LocalPath ""
|
|
||||||
CPP=cl.exe
|
|
||||||
MTL=midl.exe
|
|
||||||
RSC=rc.exe
|
|
||||||
|
|
||||||
!IF "$(CFG)" == "rpc - Win32 Release"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
|
||||||
# PROP BASE Output_Dir "..\..\Release"
|
|
||||||
# PROP BASE Intermediate_Dir "Release"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 0
|
|
||||||
# PROP Output_Dir "Release"
|
|
||||||
# PROP Intermediate_Dir "Release"
|
|
||||||
# PROP Ignore_Export_Lib 0
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "PHP_WIN32" /D "ZEND_WIN32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
|
|
||||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "NDEBUG" /D ZEND_DEBUG=0 /D "PHP_WIN32" /D "ZEND_WIN32" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_RPC" /YX /FD /c
|
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
|
||||||
# ADD BASE RSC /l 0x40d /d "NDEBUG"
|
|
||||||
# ADD RSC /l 0x40d /d "NDEBUG"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release/php_rpc.dll" /libpath:"..\..\Release"
|
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "rpc - Win32 Debug"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
|
||||||
# PROP BASE Output_Dir "..\..\Debug"
|
|
||||||
# PROP BASE Intermediate_Dir "Debug"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 1
|
|
||||||
# PROP Output_Dir "Debug"
|
|
||||||
# PROP Intermediate_Dir "Debug"
|
|
||||||
# PROP Ignore_Export_Lib 0
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "PHP_WIN32" /D "ZEND_WIN32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
|
|
||||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "_DEBUG" /D ZEND_DEBUG=1 /D "PHP_WIN32" /D "ZEND_WIN32" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_RPC" /FR /YX /FD /GZ /c
|
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
|
||||||
# ADD BASE RSC /l 0x40d /d "_DEBUG"
|
|
||||||
# ADD RSC /l 0x40d /d "_DEBUG"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug/php_rpc.dll" /pdbtype:sept /libpath:"..\..\Debug"
|
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "rpc - Win32 Debug_TS"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
|
||||||
# PROP BASE Output_Dir "..\..\Debug_TS"
|
|
||||||
# PROP BASE Intermediate_Dir "Debug_TS"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 1
|
|
||||||
# PROP Output_Dir "Debug_TS"
|
|
||||||
# PROP Intermediate_Dir "Debug_TS"
|
|
||||||
# PROP Ignore_Export_Lib 0
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "PHP_WIN32" /D "ZEND_WIN32" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c
|
|
||||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "_DEBUG" /D ZEND_DEBUG=1 /D "ZTS" /D "PHP_WIN32" /D "ZEND_WIN32" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_RPC" /FR /YX /FD /D /GZ /c
|
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
|
||||||
# ADD BASE RSC /l 0x40d /d "_DEBUG"
|
|
||||||
# ADD RSC /l 0x40d /d "_DEBUG"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts_debug.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_rpc.dll" /pdbtype:sept /libpath:"..\..\Debug_TS"
|
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "rpc - Win32 Release_TS"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
|
||||||
# PROP BASE Output_Dir "..\..\Release_TS"
|
|
||||||
# PROP BASE Intermediate_Dir "Release_TS"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 0
|
|
||||||
# PROP Output_Dir "Release_TS"
|
|
||||||
# PROP Intermediate_Dir "Release_TS"
|
|
||||||
# PROP Ignore_Export_Lib 0
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "PHP_WIN32" /D "ZEND_WIN32" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
|
|
||||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "NDEBUG" /D ZEND_DEBUG=0 /D "ZTS" /D "PHP_WIN32" /D "ZEND_WIN32" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_RPC" /YX /FD /c
|
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
|
||||||
# ADD BASE RSC /l 0x40d /d "NDEBUG"
|
|
||||||
# ADD RSC /l 0x40d /d "NDEBUG"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_rpc.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline"
|
|
||||||
|
|
||||||
!ENDIF
|
|
||||||
|
|
||||||
# Begin Target
|
|
||||||
|
|
||||||
# Name "rpc - Win32 Release"
|
|
||||||
# Name "rpc - Win32 Debug"
|
|
||||||
# Name "rpc - Win32 Debug_TS"
|
|
||||||
# Name "rpc - Win32 Release_TS"
|
|
||||||
# Begin Group "Source Files"
|
|
||||||
|
|
||||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\rpc.c
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Header Files"
|
|
||||||
|
|
||||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\handler.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\layer.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\php_rpc.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\rpc.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "tests"
|
|
||||||
|
|
||||||
# PROP Default_Filter "*.php"
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\tests\test1.php
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "layer"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Group "com"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Group "Source Files No. 1"
|
|
||||||
|
|
||||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\com\com.c
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Group "Header Files No. 1"
|
|
||||||
|
|
||||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
|
||||||
# End Group
|
|
||||||
# End Group
|
|
||||||
# End Group
|
|
||||||
# End Target
|
|
||||||
# End Project
|
|
|
@ -10,7 +10,7 @@
|
||||||
/* TODO: exception */ \
|
/* TODO: exception */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_INTERNAL_EX(intern, object) zend_hash_index_find(instance, object->value.obj.handle, (void **) &intern)
|
#define GET_INTERNAL_EX(intern, object) zend_worm_hash_index_find(instance, object->value.obj.handle, (void **) &intern)
|
||||||
|
|
||||||
#define RPC_REFCOUNT(intern) ((*intern)->refcount)
|
#define RPC_REFCOUNT(intern) ((*intern)->refcount)
|
||||||
#define RPC_ADDREF(intern) (++RPC_REFCOUNT(intern))
|
#define RPC_ADDREF(intern) (++RPC_REFCOUNT(intern))
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
<?php
|
<?php
|
||||||
print "huhuhdsa";
|
print "huhuhdsa";
|
||||||
|
|
||||||
$rpc = new com();
|
$rpc = new com("class", true);
|
||||||
$rpc->call();
|
$rpc2 = new com("class", true, "hehe", 12);
|
||||||
$rpc->addref();
|
//$rpc->call();
|
||||||
|
//$rpc->addref();
|
||||||
|
|
||||||
$clone = $rpc->__clone();
|
//$clone = $rpc->__clone();
|
||||||
|
|
||||||
//$rpc->prop = 1;
|
//$rpc->prop = 1;
|
||||||
//$a = $rpc->prop;
|
//$a = $rpc->prop;
|
||||||
|
|
||||||
$a = &$rpc->prop;
|
//$a = &$rpc->prop;
|
||||||
|
|
||||||
delete $rpc;
|
//delete $rpc;
|
||||||
delete $clone;
|
//delete $clone;
|
||||||
|
|
||||||
$heh = com_load();
|
$heh = com_load(1, 1);
|
||||||
/*$heh->call;
|
/*$heh->call;
|
||||||
delete $heh;*/
|
delete $heh;*/
|
||||||
?>
|
?>
|
Loading…
Add table
Add a link
Reference in a new issue