From 68485f8ab4df0e1b3e4f446006ce25b6be358975 Mon Sep 17 00:00:00 2001 From: Joe Watkins Date: Wed, 26 Jun 2019 13:18:50 +0200 Subject: implement tsrm_is_shutdown API --- TSRM/TSRM.c | 119 ++++++++++++++++++++++-------------------------------------- TSRM/TSRM.h | 4 +- 2 files changed, 44 insertions(+), 79 deletions(-) (limited to 'TSRM') diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index 34080eed96..1a8d5192ff 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -17,6 +17,13 @@ #include #include +#ifdef ZEND_DEBUG +# include +# define TSRM_ASSERT assert +#else +# define TSRM_ASSERT +#endif + typedef struct _tsrm_tls_entry tsrm_tls_entry; /* TSRMLS_CACHE_DEFINE; is already done in Zend, this is being always compiled statically. */ @@ -123,6 +130,7 @@ static DWORD tls_key; #endif TSRM_TLS uint8_t in_main_thread = 0; +TSRM_TLS uint8_t is_thread_shutdown = 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) @@ -141,6 +149,7 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu /* ensure singleton */ in_main_thread = 1; + is_thread_shutdown = 0; tsrm_error_file = stderr; tsrm_error_set(debug_level, debug_filename); @@ -149,6 +158,7 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu tsrm_tls_table = (tsrm_tls_entry **) calloc(tsrm_tls_table_size, sizeof(tsrm_tls_entry *)); if (!tsrm_tls_table) { TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate TLS table")); + is_thread_shutdown = 1; return 0; } id_count=0; @@ -157,8 +167,8 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu resource_types_table = (tsrm_resource_type *) calloc(resource_types_table_size, sizeof(tsrm_resource_type)); if (!resource_types_table) { TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate resource types table")); + is_thread_shutdown = 1; free(tsrm_tls_table); - tsrm_tls_table = NULL; return 0; } @@ -180,45 +190,44 @@ TSRM_API void tsrm_shutdown(void) {/*{{{*/ int i; + if (is_thread_shutdown) { + /* shutdown must only occur once */ + return; + } + + is_thread_shutdown = 1; + if (!in_main_thread) { - /* ensure singleton */ + /* only the main thread may shutdown tsrm */ return; } - if (tsrm_tls_table) { - for (i=0; inext; - for (j=0; jcount; j++) { - if (p->storage[j]) { - if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) { - resource_types_table[j].dtor(p->storage[j]); - } - if (!resource_types_table[j].fast_offset) { - free(p->storage[j]); - } + next_p = p->next; + for (j=0; jcount; j++) { + if (p->storage[j]) { + if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) { + resource_types_table[j].dtor(p->storage[j]); + } + if (!resource_types_table[j].fast_offset) { + free(p->storage[j]); } } - free(p->storage); - free(p); - p = next_p; } + free(p->storage); + free(p); + p = next_p; } - free(tsrm_tls_table); - tsrm_tls_table = NULL; - } - if (resource_types_table) { - free(resource_types_table); - resource_types_table=NULL; } + free(tsrm_tls_table); + free(resource_types_table); tsrm_mutex_free(tsmm_mutex); - tsmm_mutex = NULL; tsrm_mutex_free(tsrm_env_mutex); - tsrm_env_mutex = NULL; TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Shutdown TSRM")); if (tsrm_error_file!=stderr) { fclose(tsrm_error_file); @@ -556,6 +565,8 @@ void ts_free_thread(void) int hash_value; tsrm_tls_entry *last=NULL; + TSRM_ASSERT(!in_main_thread); + tsrm_mutex_lock(tsmm_mutex); hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size); thread_resources = tsrm_tls_table[hash_value]; @@ -590,55 +601,6 @@ void ts_free_thread(void) tsrm_mutex_unlock(tsmm_mutex); }/*}}}*/ - -/* frees all resources allocated for all threads except current */ -void ts_free_worker_threads(void) -{/*{{{*/ - tsrm_tls_entry *thread_resources; - int i; - THREAD_T thread_id = tsrm_thread_id(); - int hash_value; - tsrm_tls_entry *last=NULL; - - tsrm_mutex_lock(tsmm_mutex); - hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size); - thread_resources = tsrm_tls_table[hash_value]; - - while (thread_resources) { - if (thread_resources->thread_id != thread_id) { - for (i=0; icount; i++) { - if (resource_types_table[i].dtor) { - resource_types_table[i].dtor(thread_resources->storage[i]); - } - } - for (i=0; icount; i++) { - if (!resource_types_table[i].fast_offset) { - free(thread_resources->storage[i]); - } - } - free(thread_resources->storage); - if (last) { - last->next = thread_resources->next; - } else { - tsrm_tls_table[hash_value] = thread_resources->next; - } - free(thread_resources); - if (last) { - thread_resources = last->next; - } else { - thread_resources = tsrm_tls_table[hash_value]; - } - } else { - if (thread_resources->next) { - last = thread_resources; - } - thread_resources = thread_resources->next; - } - } - tsrm_mutex_unlock(tsmm_mutex); -}/*}}}*/ - - /* deallocates all occurrences of a given id */ void ts_free_id(ts_rsrc_id id) {/*{{{*/ @@ -885,6 +847,11 @@ TSRM_API uint8_t tsrm_is_main_thread(void) return in_main_thread; }/*}}}*/ +TSRM_API uint8_t tsrm_is_shutdown(void) +{/*{{{*/ + return is_thread_shutdown; +}/*}}}*/ + TSRM_API const char *tsrm_api_name(void) {/*{{{*/ #if defined(GNUPTH) diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index d2be318440..3c88ac3edb 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -115,9 +115,6 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id); /* frees all resources allocated for the current thread */ TSRM_API void ts_free_thread(void); -/* frees all resources allocated for all threads except current */ -void ts_free_worker_threads(void); - /* deallocates all occurrences of a given id */ TSRM_API void ts_free_id(ts_rsrc_id id); @@ -157,6 +154,7 @@ TSRM_API void tsrm_free_interpreter_context(void *context); TSRM_API void *tsrm_get_ls_cache(void); TSRM_API uint8_t tsrm_is_main_thread(void); +TSRM_API uint8_t tsrm_is_shutdown(void); TSRM_API const char *tsrm_api_name(void); #ifdef TSRM_WIN32 -- cgit v1.2.1