Index: ext/session/session.c =================================================================== --- ext/session/session.c (revision 309263) +++ ext/session/session.c (working copy) @@ -1953,6 +1953,13 @@ } /* }}} */ +static ZEND_MODULE_PRE_DEACTIVATE_D(session) /* {{{ */ +{ + php_session_flush(TSRMLS_C); + return SUCCESS; +} +/* }}} */ + static PHP_RSHUTDOWN_FUNCTION(session) /* {{{ */ { int i; @@ -2373,7 +2380,8 @@ PHP_GINIT(ps), NULL, NULL, - STANDARD_MODULE_PROPERTIES_EX + ZEND_MODULE_PRE_DEACTIVATE_N(session), + STANDARD_MODULE_PROPERTIES_EX2 }; #ifdef COMPILE_DL_SESSION Index: Zend/zend.h =================================================================== --- Zend/zend.h (revision 309263) +++ Zend/zend.h (working copy) @@ -645,6 +645,7 @@ void zend_call_destructors(TSRMLS_D); void zend_activate_modules(TSRMLS_D); void zend_deactivate_modules(TSRMLS_D); +void zend_pre_deactivate_modules(TSRMLS_D); void zend_post_deactivate_modules(TSRMLS_D); #if ZEND_DEBUG Index: Zend/zend_modules.h =================================================================== --- Zend/zend_modules.h (revision 309263) +++ Zend/zend_modules.h (working copy) @@ -33,7 +33,7 @@ #define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module TSRMLS_DC #define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module TSRMLS_CC -#define ZEND_MODULE_API_NO 20100525 +#define ZEND_MODULE_API_NO 20110316 #ifdef ZTS #define USING_ZTS 1 #else @@ -48,7 +48,7 @@ #define ZEND_MODULE_BUILD_ID "API" ZEND_TOSTR(ZEND_MODULE_API_NO) ZEND_BUILD_TS ZEND_BUILD_DEBUG ZEND_BUILD_SYSTEM ZEND_BUILD_EXTRA -#define STANDARD_MODULE_PROPERTIES_EX 0, 0, NULL, 0, ZEND_MODULE_BUILD_ID +#define STANDARD_MODULE_PROPERTIES_EX2 0, 0, NULL, 0, ZEND_MODULE_BUILD_ID #define NO_MODULE_GLOBALS 0, NULL, NULL, NULL @@ -58,6 +58,8 @@ # define ZEND_MODULE_GLOBALS(module_name) sizeof(zend_##module_name##_globals), &module_name##_globals #endif +#define STANDARD_MODULE_PROPERTIES_EX NULL, STANDARD_MODULE_PROPERTIES_EX2 + #define STANDARD_MODULE_PROPERTIES \ NO_MODULE_GLOBALS, NULL, STANDARD_MODULE_PROPERTIES_EX @@ -94,6 +96,7 @@ void (*globals_ctor)(void *global TSRMLS_DC); void (*globals_dtor)(void *global TSRMLS_DC); int (*post_deactivate_func)(void); + int (*pre_deactivate_func)(void); int module_started; unsigned char type; void *handle; Index: Zend/zend_API.c =================================================================== --- Zend/zend_API.c (revision 309263) +++ Zend/zend_API.c (working copy) @@ -2317,8 +2317,23 @@ } /* }}} */ -static int exec_done_cb(zend_module_entry *module TSRMLS_DC) /* {{{ */ +static int pre_deactivate_cb(zend_module_entry *module TSRMLS_DC) /* {{{ */ { + if (module->pre_deactivate_func) { + module->pre_deactivate_func(); + } + return 0; +} +/* }}} */ + +void zend_pre_deactivate_modules(TSRMLS_D) /* {{{ */ +{ + zend_hash_apply(&module_registry, (apply_func_t) pre_deactivate_cb TSRMLS_CC); +} +/* }}} */ + +static int post_deactivate_cb(zend_module_entry *module TSRMLS_DC) /* {{{ */ +{ if (module->post_deactivate_func) { module->post_deactivate_func(); } @@ -2329,7 +2344,7 @@ void zend_post_deactivate_modules(TSRMLS_D) /* {{{ */ { if (EG(full_tables_cleanup)) { - zend_hash_apply(&module_registry, (apply_func_t) exec_done_cb TSRMLS_CC); + zend_hash_apply(&module_registry, (apply_func_t) post_deactivate_cb TSRMLS_CC); zend_hash_reverse_apply(&module_registry, (apply_func_t) module_registry_unload_temp TSRMLS_CC); } else { zend_module_entry **p = module_post_deactivate_handlers; Index: Zend/zend_API.h =================================================================== --- Zend/zend_API.h (revision 309263) +++ Zend/zend_API.h (working copy) @@ -113,6 +113,7 @@ #define ZEND_MODULE_SHUTDOWN_N(module) zm_shutdown_##module #define ZEND_MODULE_ACTIVATE_N(module) zm_activate_##module #define ZEND_MODULE_DEACTIVATE_N(module) zm_deactivate_##module +#define ZEND_MODULE_PRE_DEACTIVATE_N(module) zm_pre_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 @@ -123,6 +124,7 @@ #define ZEND_MODULE_SHUTDOWN_D(module) int ZEND_MODULE_SHUTDOWN_N(module)(SHUTDOWN_FUNC_ARGS) #define ZEND_MODULE_ACTIVATE_D(module) int ZEND_MODULE_ACTIVATE_N(module)(INIT_FUNC_ARGS) #define ZEND_MODULE_DEACTIVATE_D(module) int ZEND_MODULE_DEACTIVATE_N(module)(SHUTDOWN_FUNC_ARGS) +#define ZEND_MODULE_PRE_DEACTIVATE_D(module) int ZEND_MODULE_PRE_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) Index: Zend/zend_execute_API.c =================================================================== --- Zend/zend_execute_API.c (revision 309263) +++ Zend/zend_execute_API.c (working copy) @@ -198,24 +198,9 @@ } /* }}} */ -static int zval_call_destructor(zval **zv TSRMLS_DC) /* {{{ */ -{ - if (Z_TYPE_PP(zv) == IS_OBJECT && Z_REFCOUNT_PP(zv) == 1) { - return ZEND_HASH_APPLY_REMOVE; - } else { - return ZEND_HASH_APPLY_KEEP; - } -} -/* }}} */ - void shutdown_destructors(TSRMLS_D) /* {{{ */ { zend_try { - int symbols; - do { - symbols = zend_hash_num_elements(&EG(symbol_table)); - zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor TSRMLS_CC); - } while (symbols != zend_hash_num_elements(&EG(symbol_table))); zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC); } zend_catch { /* if we couldn't destruct cleanly, mark all objects as destructed anyway */ Index: main/main.c =================================================================== --- main/main.c (revision 309263) +++ main/main.c (working copy) @@ -1614,12 +1614,17 @@ php_call_shutdown_functions(TSRMLS_C); } zend_end_try(); - /* 2. Call all possible __destruct() functions */ + /* 2. Call all extension pre-RSHUTDOWN functions */ + if (PG(modules_activated)) zend_try { + zend_pre_deactivate_modules(); + } zend_end_try(); + + /* 3. Call all possible __destruct() functions */ zend_try { zend_call_destructors(TSRMLS_C); } zend_end_try(); - /* 3. Flush all output buffers */ + /* 4. Flush all output buffers */ zend_try { zend_bool send_buffer = SG(request_info).headers_only ? 0 : 1; @@ -1637,18 +1642,18 @@ php_output_deactivate(TSRMLS_C); } zend_end_try(); - /* 4. Send the set HTTP headers (note: This must be done AFTER php_output_discard_all() / php_output_end_all() !!) */ + /* 5. Send the set HTTP headers (note: This must be done AFTER php_output_discard_all() / php_output_end_all() !!) */ zend_try { sapi_send_headers(TSRMLS_C); } zend_end_try(); - /* 5. Call all extensions RSHUTDOWN functions */ + /* 6. Call all extensions RSHUTDOWN functions */ if (PG(modules_activated)) { zend_deactivate_modules(TSRMLS_C); php_free_shutdown_functions(TSRMLS_C); } - /* 6. Destroy super-globals */ + /* 7. Destroy super-globals */ zend_try { int i; @@ -1659,7 +1664,7 @@ } } zend_end_try(); - /* 6.5 free last error information */ + /* 7.5 free last error information */ if (PG(last_error_message)) { free(PG(last_error_message)); PG(last_error_message) = NULL; @@ -1669,31 +1674,31 @@ PG(last_error_file) = NULL; } - /* 7. Shutdown scanner/executor/compiler and restore ini entries */ + /* 8. Shutdown scanner/executor/compiler and restore ini entries */ zend_deactivate(TSRMLS_C); - /* 8. Call all extensions post-RSHUTDOWN functions */ + /* 9. Call all extensions post-RSHUTDOWN functions */ zend_try { zend_post_deactivate_modules(TSRMLS_C); } zend_end_try(); - /* 9. SAPI related shutdown (free stuff) */ + /* 10. SAPI related shutdown (free stuff) */ zend_try { sapi_deactivate(TSRMLS_C); } zend_end_try(); - /* 10. Destroy stream hashes */ + /* 11. Destroy stream hashes */ zend_try { php_shutdown_stream_hashes(TSRMLS_C); } zend_end_try(); - /* 11. Free Willy (here be crashes) */ + /* 12. Free Willy (here be crashes) */ zend_try { shutdown_memory_manager(CG(unclean_shutdown) || !report_memleaks, 0 TSRMLS_CC); } zend_end_try(); zend_interned_strings_restore(TSRMLS_C); - /* 12. Reset max_execution_time */ + /* 13. Reset max_execution_time */ zend_try { zend_unset_timeout(TSRMLS_C); } zend_end_try();