From 2b21e7bf80004fe24feebfc00fce6210c7c3005d Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 24 Nov 2014 15:01:54 +0100 Subject: [PATCH] testing --- php_raphf.c | 46 +++++++-- php_raphf_test.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++ raphf_test.php | 37 +++++++ 3 files changed, 327 insertions(+), 7 deletions(-) create mode 100644 php_raphf_test.c create mode 100644 raphf_test.php diff --git a/php_raphf.c b/php_raphf.c index 2c785dd..8b89669 100644 --- a/php_raphf.c +++ b/php_raphf.c @@ -19,6 +19,10 @@ #include "ext/standard/info.h" #include "php_raphf.h" +#ifndef PHP_RAPHF_TEST +# define PHP_RAPHF_TEST 1 +#endif + struct php_persistent_handle_globals { ulong limit; HashTable hash; @@ -136,8 +140,11 @@ static int php_persistent_handle_apply_stat(zval *p TSRMLS_DC, int argc, add_assoc_long_ex(&zsubentry, ZEND_STRS("used"), list->used); add_assoc_long_ex(&zsubentry, ZEND_STRS("free"), zend_hash_num_elements(&list->free)); - add_assoc_zval_ex(zentry, key->key->val, key->key->len, &zsubentry); - + if (key->key) { + add_assoc_zval_ex(zentry, key->key->val, key->key->len, &zsubentry); + } else { + add_index_zval(zentry, key->h, &zsubentry); + } return ZEND_HASH_APPLY_KEEP; } @@ -152,7 +159,12 @@ static int php_persistent_handle_apply_statall(zval *p TSRMLS_DC, int argc, zend_hash_apply_with_arguments(&provider->list.free TSRMLS_CC, php_persistent_handle_apply_stat, 1, &zentry); - zend_symtable_update(ht, key->key, &zentry); + + if (key->key) { + zend_hash_update(ht, key->key, &zentry); + } else { + zend_hash_index_update(ht, key->h, &zentry); + } return ZEND_HASH_APPLY_KEEP; } @@ -226,8 +238,7 @@ static inline php_persistent_handle_list_t *php_persistent_handle_list_find( { php_persistent_handle_list_t *list; - list = zend_symtable_str_find_ptr(&provider->list.free, ident_str, - ident_len + 1); + list = zend_symtable_str_find_ptr(&provider->list.free, ident_str, ident_len); if (list) { #if PHP_RAPHF_DEBUG_PHANDLES @@ -304,7 +315,7 @@ ZEND_RESULT_CODE php_persistent_handle_provide(const char *name_str, ZVAL_PTR(&p, provider); if (zend_symtable_str_update(&PHP_RAPHF_G->persistent_handle.hash, - name_str, name_len, &p)) { + name_str, name_len + 1, &p)) { return SUCCESS; } php_resource_factory_dtor(&provider->rf); @@ -314,6 +325,7 @@ ZEND_RESULT_CODE php_persistent_handle_provide(const char *name_str, return FAILURE; } + php_persistent_handle_factory_t *php_persistent_handle_concede( php_persistent_handle_factory_t *a, const char *name_str, size_t name_len, const char *ident_str, size_t ident_len, @@ -545,6 +557,10 @@ static PHP_FUNCTION(raphf_clean_persistent_handles) } } +#if PHP_RAPHF_TEST +# include "php_raphf_test.c" +#endif + static const zend_function_entry raphf_functions[] = { ZEND_NS_FENTRY("raphf", stat_persistent_handles, ZEND_FN(raphf_stat_persistent_handles), @@ -552,6 +568,14 @@ static const zend_function_entry raphf_functions[] = { ZEND_NS_FENTRY("raphf", clean_persistent_handles, ZEND_FN(raphf_clean_persistent_handles), ai_raphf_clean_persistent_handles, 0) +#if PHP_RAPHF_TEST + ZEND_NS_FENTRY("raphf", provide, ZEND_FN(raphf_provide), NULL, 0) + ZEND_NS_FENTRY("raphf", concede, ZEND_FN(raphf_concede), NULL, 0) + ZEND_NS_FENTRY("raphf", dispute, ZEND_FN(raphf_dispute), NULL, 0) + ZEND_NS_FENTRY("raphf", handle_ctor, ZEND_FN(raphf_handle_ctor), NULL, 0) + ZEND_NS_FENTRY("raphf", handle_copy, ZEND_FN(raphf_handle_copy), NULL, 0) + ZEND_NS_FENTRY("raphf", handle_dtor, ZEND_FN(raphf_handle_dtor), NULL, 0) +#endif {0} }; @@ -583,12 +607,21 @@ static PHP_GSHUTDOWN_FUNCTION(raphf) PHP_MINIT_FUNCTION(raphf) { php_persistent_handles_global_hash = &PHP_RAPHF_G->persistent_handle.hash; + +#if PHP_RAPHF_TEST + PHP_MINIT(raphf_test)(INIT_FUNC_ARGS_PASSTHRU); +#endif + REGISTER_INI_ENTRIES(); return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(raphf) { +#if PHP_RAPHF_TEST + PHP_MSHUTDOWN(raphf_test)(SHUTDOWN_FUNC_ARGS_PASSTHRU); +#endif + UNREGISTER_INI_ENTRIES(); php_persistent_handles_global_hash = NULL; return SUCCESS; @@ -667,7 +700,6 @@ zend_module_entry raphf_module_entry = { ZEND_GET_MODULE(raphf) #endif - /* * Local variables: * tab-width: 4 diff --git a/php_raphf_test.c b/php_raphf_test.c new file mode 100644 index 0000000..6d59789 --- /dev/null +++ b/php_raphf_test.c @@ -0,0 +1,251 @@ +/* + +--------------------------------------------------------------------+ + | PECL :: raphf | + +--------------------------------------------------------------------+ + | Redistribution and use in source and binary forms, with or without | + | modification, are permitted provided that the conditions mentioned | + | in the accompanying LICENSE file are met. | + +--------------------------------------------------------------------+ + | Copyright (c) 2014, Michael Wallner | + +--------------------------------------------------------------------+ +*/ + +#include + +struct user_cb { + zend_fcall_info fci; + zend_fcall_info_cache fcc; +}; + +struct raphf_user { + struct user_cb ctor; + struct user_cb copy; + struct user_cb dtor; + struct { + struct user_cb dtor; + zval data; + } data; +}; + +static inline void user_cb_addref(struct user_cb *cb) +{ + Z_ADDREF(cb->fci.function_name); + if (cb->fci.object) { + Z_ADDREF_P((zval *) cb->fci.object); + } +} + +static inline void user_cb_delref(struct user_cb *cb) +{ + if (cb->fci.object) { + Z_DELREF_P((zval *) cb->fci.object); + } +} + +static void raphf_user_dtor(void *opaque) +{ + struct raphf_user *ru = opaque; + + fprintf(stderr, "Freeing raphf_user struct\n"); + zend_fcall_info_argn(&ru->data.dtor.fci, 1, &ru->data.data); + zend_fcall_info_call(&ru->data.dtor.fci, &ru->data.dtor.fcc, NULL, NULL); + zend_fcall_info_args_clear(&ru->data.dtor.fci, 1); + user_cb_delref(&ru->data.dtor); + zend_fcall_info_args_clear(&ru->ctor.fci, 1); + user_cb_delref(&ru->ctor); + zend_fcall_info_args_clear(&ru->copy.fci, 1); + user_cb_delref(&ru->copy); + zend_fcall_info_args_clear(&ru->dtor.fci, 1); + user_cb_delref(&ru->dtor); + memset(ru, 0, sizeof(*ru)); + efree(ru); +} + +static void *user_ctor(void *opaque, void *init_arg TSRMLS_DC) +{ + struct raphf_user *ru = opaque; + zval *zinit_arg = init_arg, *retval = ecalloc(1, sizeof(*retval)); + + zend_fcall_info_argn(&ru->ctor.fci, 2, &ru->data.data, zinit_arg); + zend_fcall_info_call(&ru->ctor.fci, &ru->ctor.fcc, retval, NULL); + zend_fcall_info_args_clear(&ru->ctor.fci, 0); + + return retval; +} + +static void *user_copy(void *opaque, void *handle TSRMLS_DC) +{ + struct raphf_user *ru = opaque; + zval *zhandle = handle, *retval = ecalloc(1, sizeof(*retval)); + + zend_fcall_info_argn(&ru->copy.fci, 2, &ru->data.data, zhandle); + zend_fcall_info_call(&ru->copy.fci, &ru->copy.fcc, retval, NULL); + zend_fcall_info_args_clear(&ru->copy.fci, 0); + + return retval; +} + +static void user_dtor(void *opaque, void *handle TSRMLS_DC) +{ + struct raphf_user *ru = opaque; + zval *zhandle = handle, retval; + + ZVAL_UNDEF(&retval); + zend_fcall_info_argn(&ru->dtor.fci, 2, &ru->data.data, zhandle); + zend_fcall_info_call(&ru->dtor.fci, &ru->dtor.fcc, &retval, NULL); + zend_fcall_info_args_clear(&ru->dtor.fci, 0); + if (!Z_ISUNDEF(retval)) { + zval_ptr_dtor(&retval); + } +} + +static php_resource_factory_ops_t user_ops = { + user_ctor, + user_copy, + user_dtor +}; + +static int raphf_user_le; + +static void raphf_user_res_dtor(zend_resource *res TSRMLS_DC) +{ + php_resource_factory_free((void *) &res->ptr); +} + +static PHP_FUNCTION(raphf_provide) +{ + struct raphf_user *ru; + char *name_str; + size_t name_len; + zval *zdata; + + ru = ecalloc(1, sizeof(*ru)); + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sfffzf", + &name_str, &name_len, + &ru->ctor.fci, &ru->ctor.fcc, + &ru->copy.fci, &ru->copy.fcc, + &ru->dtor.fci, &ru->dtor.fcc, + &zdata, + &ru->data.dtor.fci, &ru->data.dtor.fcc)) { + efree(ru); + return; + } + + user_cb_addref(&ru->ctor); + user_cb_addref(&ru->copy); + user_cb_addref(&ru->dtor); + user_cb_addref(&ru->data.dtor); + + ZVAL_COPY(&ru->data.data, zdata); + + if (SUCCESS != php_persistent_handle_provide(name_str, name_len, + &user_ops, ru, raphf_user_dtor)) { + return; + } +} + +static PHP_FUNCTION(raphf_concede) +{ + char *name_str, *id_str; + size_t name_len, id_len; + php_persistent_handle_factory_t *pf; + php_resource_factory_t *rf; + php_resource_factory_ops_t *ops; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", + &name_str, &name_len, &id_str, &id_len)) { + return; + } + + ops = php_persistent_handle_get_resource_factory_ops(); + pf = php_persistent_handle_concede(NULL, name_str, name_len, id_str, id_len, + NULL, NULL TSRMLS_CC); + if (!pf) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Could not locate persistent handle factory '%s'", name_str); + RETURN_FALSE; + } + rf = php_resource_factory_init(NULL, ops, pf, + (void(*)(void*)) php_persistent_handle_abandon); + if (!rf) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Could not create resource factory " + "for persistent handle factory '%s'", name_str); + RETURN_FALSE; + } + + zend_register_resource(return_value, rf, raphf_user_le); +} + +static PHP_FUNCTION(raphf_dispute) +{ + zval *zrf; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zrf)) { + return; + } + + zend_list_close(Z_RES_P(zrf)); +} + +static PHP_FUNCTION(raphf_handle_ctor) +{ + zval *zrf, *zrv, *zinit_arg; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", + &zrf, &zinit_arg)) { + return; + } + + zrv = php_resource_factory_handle_ctor(Z_RES_VAL_P(zrf), zinit_arg); + RETVAL_ZVAL(zrv, 0, 0); + efree(zrv); +} + +static PHP_FUNCTION(raphf_handle_copy) +{ + zval *zrf, *zrv, *zhandle; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", + &zrf, &zhandle)) { + return; + } + + zrv = php_resource_factory_handle_copy(Z_RES_VAL_P(zrf), zhandle); + RETVAL_ZVAL(zrv, 0, 0); + efree(zrv); +} + +static PHP_FUNCTION(raphf_handle_dtor) +{ + zval *zrf, *zhandle; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", + &zrf, &zhandle)) { + return; + } + + php_resource_factory_handle_dtor(Z_RES_VAL_P(zrf), zhandle); +} + +static PHP_MINIT_FUNCTION(raphf_test) +{ + raphf_user_le = zend_register_list_destructors_ex(raphf_user_res_dtor, NULL, + "raphf_user", module_number); + return SUCCESS; +} + +static PHP_MSHUTDOWN_FUNCTION(raphf_test) +{ + php_persistent_handle_cleanup(ZEND_STRL("test"), NULL, 0 TSRMLS_CC); + return SUCCESS; +} +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/raphf_test.php b/raphf_test.php new file mode 100644 index 0000000..70b06de --- /dev/null +++ b/raphf_test.php @@ -0,0 +1,37 @@ +