Hi, The attached patch (for PHP_5_2) implements automatic management of module globals. The problem that module globals must be unregistered before extension unloading, because "globls_dtor" function is unloaded together with extension and cannot be called.
To solve this problem extension writers now use the following pattern: PHP_MSHUTDOWN_FUNCTION(mod_name) { -#ifdef ZTS - ts_free_id(mod_name_globals_id); -#else - mod_name_globals_dtor(&mod_name_globals TSRMLS_CC); -#endif With my patch, extension writers should just extend module descriptor with globals descriptor and ctor/dtor callbacks. PHP_RSHUTDOWN(mod_name), PHP_MINFO(mod_name), NO_VERSION_YET, - STANDARD_MODULE_PROPERTIES + NULL, + ZEND_MG(mod_name), + ZEND_MGCTOR(mod_name), + ZEND_MGCTOR(mod_name), + STANDARD_MODULE_PROPERTIES_EX2 }; Old extensions are source compatible and may work without modification. The patch modifies only several extensions, but will modify others too. I like commit the patch into HEAD and PHP_5_2. Any objections, additional ideas? Thanks. Dmitry.
Index: Zend/zend_API.c =================================================================== RCS file: /repository/ZendEngine2/zend_API.c,v retrieving revision 1.296.2.27.2.17 diff -u -p -d -r1.296.2.27.2.17 zend_API.c --- Zend/zend_API.c 7 Jun 2006 09:43:54 -0000 1.296.2.27.2.17 +++ Zend/zend_API.c 8 Jun 2006 10:52:52 -0000 @@ -1448,6 +1448,15 @@ ZEND_API int zend_startup_module_ex(zend } } + if (module->globals_size) { +#ifdef ZTS + ts_allocate_id(module->globals_id_ptr, module->globals_size, (ts_allocate_ctor) module->globals_ctor, (ts_allocate_dtor) module->globals_dtor); +#else + if (module->globals_ctor) { + module->globals_ctor(module->globals_ptr TSRMLS_CC); + } +#endif + } if (module->module_startup_func) { EG(current_module) = module; if (module->module_startup_func(module->type, module->module_number TSRMLS_CC)==FAILURE) { @@ -1881,6 +1890,17 @@ void module_destructor(zend_module_entry #endif module->module_shutdown_func(module->type, module->module_number TSRMLS_CC); } + + if (module->globals_size) { +#ifdef ZTS + ts_free_id(*module->globals_id_ptr); +#else + if (module->globals_dtor) { + module->globals_dtor(module->globals_ptr TSRMLS_CC); + } +#endif + } + module->module_started=0; if (module->functions) { zend_unregister_functions(module->functions, -1, NULL TSRMLS_CC); Index: Zend/zend_API.h =================================================================== RCS file: /repository/ZendEngine2/zend_API.h,v retrieving revision 1.207.2.8.2.3 diff -u -p -d -r1.207.2.8.2.3 zend_API.h --- Zend/zend_API.h 7 Jun 2006 09:43:54 -0000 1.207.2.8.2.3 +++ Zend/zend_API.h 8 Jun 2006 10:52:52 -0000 @@ -79,6 +79,8 @@ typedef struct _zend_function_entry { #define ZEND_MODULE_DEACTIVATE_N(module) zm_deactivate_##module #define ZEND_MODULE_POST_ZEND_DEACTIVATE_N(module) zm_post_zend_deactivate_##module #define ZEND_MODULE_INFO_N(module) zm_info_##module +#define ZEND_MODULE_GLOBALS_CTOR_N(module) zm_globals_ctor_##module +#define ZEND_MODULE_GLOBALS_DTOR_N(module) zm_globals_dtor_##module /* Declaration macros */ #define ZEND_MODULE_STARTUP_D(module) int ZEND_MODULE_STARTUP_N(module)(INIT_FUNC_ARGS) @@ -87,6 +89,8 @@ typedef struct _zend_function_entry { #define ZEND_MODULE_DEACTIVATE_D(module) int ZEND_MODULE_DEACTIVATE_N(module)(SHUTDOWN_FUNC_ARGS) #define ZEND_MODULE_POST_ZEND_DEACTIVATE_D(module) int ZEND_MODULE_POST_ZEND_DEACTIVATE_N(module)(void) #define ZEND_MODULE_INFO_D(module) void ZEND_MODULE_INFO_N(module)(ZEND_MODULE_INFO_FUNC_ARGS) +#define ZEND_MODULE_GLOBALS_CTOR_D(module) void ZEND_MODULE_GLOBALS_CTOR_N(module)(zend_##module##_globals *module##_globals TSRMLS_DC) +#define ZEND_MODULE_GLOBALS_DTOR_D(module) void ZEND_MODULE_GLOBALS_DTOR_N(module)(zend_##module##_globals *module##_globals TSRMLS_DC) #define ZEND_GET_MODULE(name) \ BEGIN_EXTERN_C()\ @@ -611,12 +615,16 @@ END_EXTERN_C() #define ZEND_RINIT ZEND_MODULE_ACTIVATE_N #define ZEND_RSHUTDOWN ZEND_MODULE_DEACTIVATE_N #define ZEND_MINFO ZEND_MODULE_INFO_N +#define ZEND_MGCTOR(module) ((void (*)(void* TSRMLS_DC))(ZEND_MODULE_GLOBALS_CTOR_N(module))) +#define ZEND_MGDTOR(module) ((void (*)(void* TSRMLS_DC))(ZEND_MODULE_GLOBALS_DTOR_N(module))) #define ZEND_MINIT_FUNCTION ZEND_MODULE_STARTUP_D #define ZEND_MSHUTDOWN_FUNCTION ZEND_MODULE_SHUTDOWN_D #define ZEND_RINIT_FUNCTION ZEND_MODULE_ACTIVATE_D #define ZEND_RSHUTDOWN_FUNCTION ZEND_MODULE_DEACTIVATE_D #define ZEND_MINFO_FUNCTION ZEND_MODULE_INFO_D +#define ZEND_MGCTOR_FUNCTION ZEND_MODULE_GLOBALS_CTOR_D +#define ZEND_MGDTOR_FUNCTION ZEND_MODULE_GLOBALS_DTOR_D END_EXTERN_C() Index: Zend/zend_modules.h =================================================================== RCS file: /repository/ZendEngine2/zend_modules.h,v retrieving revision 1.67.2.3.2.1 diff -u -p -d -r1.67.2.3.2.1 zend_modules.h --- Zend/zend_modules.h 9 May 2006 23:53:23 -0000 1.67.2.3.2.1 +++ Zend/zend_modules.h 8 Jun 2006 10:52:53 -0000 @@ -39,7 +39,7 @@ extern struct _zend_arg_info fourth_arg_ extern struct _zend_arg_info fifth_arg_force_ref[6]; extern struct _zend_arg_info all_args_by_ref[1]; -#define ZEND_MODULE_API_NO 20050922 +#define ZEND_MODULE_API_NO 20060601 #ifdef ZTS #define USING_ZTS 1 #else @@ -52,7 +52,11 @@ extern struct _zend_arg_info all_args_by #define ZE2_STANDARD_MODULE_HEADER \ STANDARD_MODULE_HEADER_EX, ini_entries, NULL -#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0 +#define STANDARD_MODULE_PROPERTIES_EX \ + 0, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES_EX2 + +#define STANDARD_MODULE_PROPERTIES_EX2 \ + 0, 0, NULL, 0 #define STANDARD_MODULE_PROPERTIES \ NULL, STANDARD_MODULE_PROPERTIES_EX @@ -82,13 +86,26 @@ struct _zend_module_entry { void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS); char *version; int (*post_deactivate_func)(void); - int globals_id; + size_t globals_size; +#ifdef ZTS + ts_rsrc_id* globals_id_ptr; +#else + void* globals_ptr; +#endif + void (*globals_ctor)(void *global TSRMLS_DC); + void (*globals_dtor)(void *global TSRMLS_DC); int module_started; unsigned char type; void *handle; int module_number; }; +#ifdef ZTS +# define ZEND_MG(module_name) sizeof(zend_##module_name##_globals), &module_name##_globals_id +#else +# define ZEND_MG(module_name) sizeof(zend_##module_name##_globals), &module_name##_globals +#endif + #define MODULE_DEP_REQUIRED 1 #define MODULE_DEP_CONFLICTS 2 #define MODULE_DEP_OPTIONAL 3 Index: ext/bcmath/bcmath.c =================================================================== RCS file: /repository/php-src/ext/bcmath/bcmath.c,v retrieving revision 1.62.2.2 diff -u -p -d -r1.62.2.2 bcmath.c --- ext/bcmath/bcmath.c 1 Jan 2006 12:50:00 -0000 1.62.2.2 +++ ext/bcmath/bcmath.c 8 Jun 2006 10:52:58 -0000 @@ -31,6 +31,8 @@ #include "php_bcmath.h" #include "libbcmath/src/bcmath.h" +static ZEND_MGCTOR_FUNCTION(bcmath); + ZEND_DECLARE_MODULE_GLOBALS(bcmath); zend_function_entry bcmath_functions[] = { @@ -57,7 +59,11 @@ zend_module_entry bcmath_module_entry = PHP_RSHUTDOWN(bcmath), PHP_MINFO(bcmath), NO_VERSION_YET, - STANDARD_MODULE_PROPERTIES + NULL, + ZEND_MG(bcmath), + ZEND_MGCTOR(bcmath), + NULL, + STANDARD_MODULE_PROPERTIES_EX2 }; #ifdef COMPILE_DL_BCMATH @@ -72,7 +78,7 @@ PHP_INI_END() /* {{{ php_bcmath_init_globals */ -static void php_bcmath_init_globals(zend_bcmath_globals *bcmath_globals) +static ZEND_MGCTOR_FUNCTION(bcmath) { bcmath_globals->bc_precision = 0; } @@ -82,8 +88,6 @@ static void php_bcmath_init_globals(zend */ PHP_MINIT_FUNCTION(bcmath) { - ZEND_INIT_MODULE_GLOBALS(bcmath, php_bcmath_init_globals, NULL); - REGISTER_INI_ENTRIES(); return SUCCESS; Index: ext/date/php_date.c =================================================================== RCS file: /repository/php-src/ext/date/php_date.c,v retrieving revision 1.43.2.45.2.6 diff -u -p -d -r1.43.2.45.2.6 php_date.c --- ext/date/php_date.c 30 May 2006 15:14:22 -0000 1.43.2.45.2.6 +++ ext/date/php_date.c 8 Jun 2006 10:52:59 -0000 @@ -29,6 +29,8 @@ #include "lib/timelib.h" #include <time.h> +static ZEND_MGCTOR_FUNCTION(date); + /* {{{ Function table */ zend_function_entry date_functions[] = { PHP_FE(strtotime, NULL) @@ -188,13 +190,17 @@ zend_module_entry date_module_entry = { PHP_RSHUTDOWN(date), /* request shutdown */ PHP_MINFO(date), /* extension info */ PHP_VERSION, /* extension version */ - STANDARD_MODULE_PROPERTIES + NULL, + ZEND_MG(date), + ZEND_MGCTOR(date), + NULL, + STANDARD_MODULE_PROPERTIES_EX2 }; /* }}} */ /* {{{ php_date_init_globals */ -static void php_date_init_globals(zend_date_globals *date_globals) +static ZEND_MGCTOR_FUNCTION(date) { date_globals->default_timezone = NULL; date_globals->timezone = NULL; @@ -334,7 +340,6 @@ PHP_RSHUTDOWN_FUNCTION(date) /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(date) { - ZEND_INIT_MODULE_GLOBALS(date, php_date_init_globals, NULL); REGISTER_INI_ENTRIES(); #ifdef EXPERIMENTAL_DATE_SUPPORT date_register_classes(TSRMLS_C); Index: ext/pcre/php_pcre.c =================================================================== RCS file: /repository/php-src/ext/pcre/php_pcre.c,v retrieving revision 1.168.2.9.2.4 diff -u -p -d -r1.168.2.9.2.4 php_pcre.c --- ext/pcre/php_pcre.c 29 May 2006 21:31:49 -0000 1.168.2.9.2.4 +++ ext/pcre/php_pcre.c 8 Jun 2006 10:53:02 -0000 @@ -97,7 +97,7 @@ static void php_free_pcre_cache(void *da } -static void php_pcre_init_globals(zend_pcre_globals *pcre_globals TSRMLS_DC) +static ZEND_MGCTOR_FUNCTION(pcre) { zend_hash_init(&pcre_globals->pcre_cache, 0, NULL, php_free_pcre_cache, 1); pcre_globals->backtrack_limit = 0; @@ -105,7 +105,7 @@ static void php_pcre_init_globals(zend_p pcre_globals->error_code = PHP_PCRE_NO_ERROR; } -static void php_pcre_shutdown_globals(zend_pcre_globals *pcre_globals TSRMLS_DC) +static ZEND_MGDTOR_FUNCTION(pcre) { zend_hash_destroy(&pcre_globals->pcre_cache); } @@ -129,8 +129,6 @@ static PHP_MINFO_FUNCTION(pcre) /* {{{ PHP_MINIT_FUNCTION(pcre) */ static PHP_MINIT_FUNCTION(pcre) { - ZEND_INIT_MODULE_GLOBALS(pcre, php_pcre_init_globals, php_pcre_shutdown_globals); - REGISTER_INI_ENTRIES(); REGISTER_LONG_CONSTANT("PREG_PATTERN_ORDER", PREG_PATTERN_ORDER, CONST_CS | CONST_PERSISTENT); @@ -154,12 +152,6 @@ static PHP_MINIT_FUNCTION(pcre) /* {{{ PHP_MSHUTDOWN_FUNCTION(pcre) */ static PHP_MSHUTDOWN_FUNCTION(pcre) { -#ifdef ZTS - ts_free_id(pcre_globals_id); -#else - php_pcre_shutdown_globals(&pcre_globals TSRMLS_CC); -#endif - UNREGISTER_INI_ENTRIES(); return SUCCESS; @@ -1776,7 +1768,11 @@ zend_module_entry pcre_module_entry = { NULL, PHP_MINFO(pcre), NO_VERSION_YET, - STANDARD_MODULE_PROPERTIES + NULL, + ZEND_MG(pcre), + ZEND_MGCTOR(pcre), + ZEND_MGDTOR(pcre), + STANDARD_MODULE_PROPERTIES_EX2 }; #ifdef COMPILE_DL_PCRE Index: ext/pdo/pdo.c =================================================================== RCS file: /repository/php-src/ext/pdo/pdo.c,v retrieving revision 1.57.2.17.2.5 diff -u -p -d -r1.57.2.17.2.5 pdo.c --- ext/pdo/pdo.c 7 Jun 2006 21:14:04 -0000 1.57.2.17.2.5 +++ ext/pdo/pdo.c 8 Jun 2006 10:53:02 -0000 @@ -130,6 +130,8 @@ static zend_module_dep pdo_deps[] = { #endif /* }}} */ +static ZEND_MGCTOR_FUNCTION(pdo); + /* {{{ pdo_module_entry */ zend_module_entry pdo_module_entry = { #if ZEND_MODULE_API_NO >= 20050922 @@ -146,7 +148,11 @@ zend_module_entry pdo_module_entry = { NULL, PHP_MINFO(pdo), "1.0.4dev", - STANDARD_MODULE_PROPERTIES + NULL, + ZEND_MG(pdo), + ZEND_MGCTOR(pdo), + NULL, + STANDARD_MODULE_PROPERTIES_EX2 }; /* }}} */ @@ -164,7 +170,7 @@ PHP_INI_END() /* }}} */ /* {{{ php_pdo_init_globals */ -static void php_pdo_init_globals(zend_pdo_globals *pdo_globals) +static ZEND_MGCTOR_FUNCTION(pdo) { pdo_globals->global_value = 0; } @@ -321,7 +327,6 @@ PHP_MINIT_FUNCTION(pdo) spl_ce_RuntimeException = NULL; - ZEND_INIT_MODULE_GLOBALS(pdo, php_pdo_init_globals, NULL); REGISTER_INI_ENTRIES(); if (FAILURE == pdo_sqlstate_init_error_table()) { Index: ext/posix/posix.c =================================================================== RCS file: /repository/php-src/ext/posix/posix.c,v retrieving revision 1.70.2.3 diff -u -p -d -r1.70.2.3 posix.c --- ext/posix/posix.c 1 Jan 2006 12:50:12 -0000 1.70.2.3 +++ ext/posix/posix.c 8 Jun 2006 10:53:06 -0000 @@ -148,7 +148,7 @@ static PHP_MINFO_FUNCTION(posix) } /* }}} */ -static void php_posix_init_globals(zend_posix_globals *posix_globals TSRMLS_DC) +static ZEND_MGCTOR_FUNCTION(posix) { posix_globals->last_error = 0; } @@ -157,7 +157,6 @@ static void php_posix_init_globals(zend_ */ static PHP_MINIT_FUNCTION(posix) { - ZEND_INIT_MODULE_GLOBALS(posix, php_posix_init_globals, NULL); REGISTER_LONG_CONSTANT("POSIX_F_OK", F_OK, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("POSIX_X_OK", X_OK, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("POSIX_W_OK", W_OK, CONST_CS | CONST_PERSISTENT); @@ -196,7 +195,11 @@ zend_module_entry posix_module_entry = { NULL, PHP_MINFO(posix), NO_VERSION_YET, - STANDARD_MODULE_PROPERTIES + NULL, + ZEND_MG(posix), + ZEND_MGCTOR(posix), + NULL, + STANDARD_MODULE_PROPERTIES_EX2 }; /* }}} */ Index: ext/spl/php_spl.c =================================================================== RCS file: /repository/php-src/ext/spl/php_spl.c,v retrieving revision 1.52.2.28.2.2 diff -u -p -d -r1.52.2.28.2.2 php_spl.c --- ext/spl/php_spl.c 7 Jun 2006 09:44:41 -0000 1.52.2.28.2.2 +++ ext/spl/php_spl.c 8 Jun 2006 10:53:06 -0000 @@ -52,7 +52,7 @@ zend_function_entry spl_functions_none[] /* {{{ spl_init_globals */ -static void spl_init_globals(zend_spl_globals *spl_globals) +static ZEND_MGCTOR_FUNCTION(spl) { spl_globals->autoload_extensions = NULL; spl_globals->autoload_functions = NULL; @@ -645,8 +645,6 @@ zend_function_entry spl_functions[] = { */ PHP_MINIT_FUNCTION(spl) { - ZEND_INIT_MODULE_GLOBALS(spl, spl_init_globals, NULL); - PHP_MINIT(spl_iterators)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(spl_array)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(spl_directory)(INIT_FUNC_ARGS_PASSTHRU); @@ -704,7 +702,11 @@ zend_module_entry spl_module_entry = { PHP_RSHUTDOWN(spl), PHP_MINFO(spl), "0.2", - STANDARD_MODULE_PROPERTIES + NULL, + ZEND_MG(spl), + ZEND_MGCTOR(spl), + NULL, + STANDARD_MODULE_PROPERTIES_EX2 }; /* }}} */ Index: ext/sqlite/sqlite.c =================================================================== RCS file: /repository/php-src/ext/sqlite/sqlite.c,v retrieving revision 1.166.2.13.2.1 diff -u -p -d -r1.166.2.13.2.1 sqlite.c --- ext/sqlite/sqlite.c 9 May 2006 23:54:15 -0000 1.166.2.13.2.1 +++ ext/sqlite/sqlite.c 8 Jun 2006 10:53:12 -0000 @@ -283,6 +283,8 @@ static zend_module_dep sqlite_deps[] = { {NULL, NULL, NULL} }; +static ZEND_MGCTOR_FUNCTION(sqlite); + zend_module_entry sqlite_module_entry = { #if ZEND_MODULE_API_NO >= 20050922 STANDARD_MODULE_HEADER_EX, NULL, @@ -300,7 +302,11 @@ zend_module_entry sqlite_module_entry = #if ZEND_MODULE_API_NO >= 20010901 PHP_SQLITE_MODULE_VERSION, #endif - STANDARD_MODULE_PROPERTIES + NULL, + ZEND_MG(sqlite), + ZEND_MGCTOR(sqlite), + NULL, + STANDARD_MODULE_PROPERTIES_EX2 }; @@ -1016,10 +1022,9 @@ zend_object_iterator *sqlite_get_iterato } /* }}} */ -static int init_sqlite_globals(zend_sqlite_globals *g) +static ZEND_MGCTOR_FUNCTION(sqlite) { - g->assoc_case = 0; - return SUCCESS; + sqlite_globals->assoc_case = 0; } PHP_MINIT_FUNCTION(sqlite) @@ -1051,8 +1056,6 @@ PHP_MINIT_FUNCTION(sqlite) sqlite_ce_query->get_iterator = sqlite_get_iterator; sqlite_ce_query->iterator_funcs.funcs = &sqlite_query_iterator_funcs; - ZEND_INIT_MODULE_GLOBALS(sqlite, init_sqlite_globals, NULL); - REGISTER_INI_ENTRIES(); #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) Index: ext/zlib/zlib.c =================================================================== RCS file: /repository/php-src/ext/zlib/zlib.c,v retrieving revision 1.183.2.6 diff -u -p -d -r1.183.2.6 zlib.c --- ext/zlib/zlib.c 1 Jan 2006 12:50:17 -0000 1.183.2.6 +++ ext/zlib/zlib.c 8 Jun 2006 10:53:13 -0000 @@ -113,6 +113,8 @@ zend_function_entry php_zlib_functions[] }; /* }}} */ +ZEND_DECLARE_MODULE_GLOBALS(zlib) + /* {{{ php_zlib_module_entry */ zend_module_entry php_zlib_module_entry = { @@ -125,12 +127,14 @@ zend_module_entry php_zlib_module_entry NULL, PHP_MINFO(zlib), "1.1", - STANDARD_MODULE_PROPERTIES + NULL, + ZEND_MG(zlib), + NULL, + NULL, + STANDARD_MODULE_PROPERTIES_EX2 }; /* }}} */ -ZEND_DECLARE_MODULE_GLOBALS(zlib) - #ifdef COMPILE_DL_ZLIB ZEND_GET_MODULE(php_zlib) #endif @@ -212,9 +216,6 @@ static void php_zlib_init_globals(zend_z */ PHP_MINIT_FUNCTION(zlib) { -#ifdef ZTS - ts_allocate_id(&zlib_globals_id, sizeof(zend_zlib_globals), (ts_allocate_ctor) php_zlib_init_globals, NULL); -#endif php_register_url_stream_wrapper("compress.zlib", &php_stream_gzip_wrapper TSRMLS_CC); php_stream_filter_register_factory("zlib.*", &php_zlib_filter_factory TSRMLS_CC);
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php