diff options
Diffstat (limited to 'TSRM')
-rw-r--r-- | TSRM/TSRM.c | 31 | ||||
-rw-r--r-- | TSRM/TSRM.h | 2 |
2 files changed, 29 insertions, 4 deletions
diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index 6669df6d43..2c7a40a2de 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -55,8 +55,9 @@ static int resource_types_table_size; static MUTEX_T tsmm_mutex; /* thread-safe memory manager mutex */ /* New thread handlers */ -static tsrm_thread_begin_func_t tsrm_new_thread_begin_handler; -static tsrm_thread_end_func_t tsrm_new_thread_end_handler; +static tsrm_thread_begin_func_t tsrm_new_thread_begin_handler = NULL; +static tsrm_thread_end_func_t tsrm_new_thread_end_handler = NULL; +static tsrm_shutdown_func_t tsrm_shutdown_handler = NULL; /* Debug support */ int tsrm_error(int level, const char *format, ...); @@ -120,6 +121,8 @@ static int32 tls_key; # warning tsrm_set_interpreter_context is probably broken on this platform #endif +TSRM_TLS uint8_t in_main_thread = 0; + /* Startup TSRM (call once for the entire process) */ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename) { @@ -136,6 +139,9 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu tls_key = tls_allocate(); #endif + /* ensure singleton */ + in_main_thread = 1; + tsrm_error_file = stderr; tsrm_error_set(debug_level, debug_filename); tsrm_tls_table_size = expected_threads; @@ -158,8 +164,6 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu tsmm_mutex = tsrm_mutex_alloc(); - tsrm_new_thread_begin_handler = tsrm_new_thread_end_handler = NULL; - TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Started up TSRM, %d expected threads, %d expected resources", expected_threads, expected_resources)); return 1; } @@ -170,6 +174,11 @@ TSRM_API void tsrm_shutdown(void) { int i; + if (!in_main_thread) { + /* ensure singleton */ + return; + } + if (tsrm_tls_table) { for (i=0; i<tsrm_tls_table_size; i++) { tsrm_tls_entry *p = tsrm_tls_table[i], *next_p; @@ -212,6 +221,12 @@ TSRM_API void tsrm_shutdown(void) #elif defined(TSRM_WIN32) TlsFree(tls_key); #endif + if (tsrm_shutdown_handler) { + tsrm_shutdown_handler(); + } + tsrm_new_thread_begin_handler = NULL; + tsrm_new_thread_end_handler = NULL; + tsrm_shutdown_handler = NULL; } @@ -740,6 +755,14 @@ TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread } +TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler) +{ + void *retval = (void *) tsrm_shutdown_handler; + + tsrm_shutdown_handler = shutdown_handler; + return retval; +} + /* * Debug support diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index f9bb241050..2ffcbfee76 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -128,6 +128,7 @@ TSRM_API void ts_free_id(ts_rsrc_id id); typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id); typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id); +typedef void (*tsrm_shutdown_func_t)(void); TSRM_API int tsrm_error(int level, const char *format, ...); @@ -145,6 +146,7 @@ TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset); TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler); TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler); +TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler); /* these 3 APIs should only be used by people that fully understand the threading model * used by PHP/Zend and the selected SAPI. */ |