summaryrefslogtreecommitdiff
path: root/TSRM
diff options
context:
space:
mode:
authorJoe Watkins <krakjoe@php.net>2019-06-26 13:18:50 +0200
committerJoe Watkins <krakjoe@php.net>2019-06-28 10:27:19 +0200
commit68485f8ab4df0e1b3e4f446006ce25b6be358975 (patch)
treec4b9011936860d33810039a4f95b48d9bc77420d /TSRM
parentbc0db8ce453aab34941cfe510833d218e50fcae4 (diff)
downloadphp-git-68485f8ab4df0e1b3e4f446006ce25b6be358975.tar.gz
implement tsrm_is_shutdown API
Diffstat (limited to 'TSRM')
-rw-r--r--TSRM/TSRM.c119
-rw-r--r--TSRM/TSRM.h4
2 files changed, 44 insertions, 79 deletions
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 <stdio.h>
#include <stdarg.h>
+#ifdef ZEND_DEBUG
+# include <assert.h>
+# 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; i<tsrm_tls_table_size; i++) {
- tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;
+ for (i=0; i<tsrm_tls_table_size; i++) {
+ tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;
- while (p) {
- int j;
+ while (p) {
+ int j;
- next_p = p->next;
- for (j=0; j<p->count; 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; j<p->count; 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; i<thread_resources->count; i++) {
- if (resource_types_table[i].dtor) {
- resource_types_table[i].dtor(thread_resources->storage[i]);
- }
- }
- for (i=0; i<thread_resources->count; 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