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