summaryrefslogtreecommitdiff
path: root/TSRM
diff options
context:
space:
mode:
authorJoe Watkins <krakjoe@php.net>2019-06-28 10:27:39 +0200
committerJoe Watkins <krakjoe@php.net>2019-06-28 10:27:39 +0200
commitb98cd0719a51904c1d3813cb7926494ea7623a92 (patch)
treebd57ed355e897ab5ef3b14b2ab655136f70fad5d /TSRM
parent0504f045914a7bdef6905f54167fb9722a5de7e2 (diff)
parent68485f8ab4df0e1b3e4f446006ce25b6be358975 (diff)
downloadphp-git-b98cd0719a51904c1d3813cb7926494ea7623a92.tar.gz
Merge branch 'PHP-7.4'
* PHP-7.4: 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 132dc05c65..bcd5c806b1 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. */
@@ -106,6 +113,7 @@ static pthread_key_t 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)
@@ -118,6 +126,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);
@@ -126,6 +135,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;
@@ -134,8 +144,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;
}
@@ -157,45 +167,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);
@@ -470,6 +479,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];
@@ -504,55 +515,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)
{/*{{{*/
@@ -789,6 +751,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(TSRM_WIN32)
diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h
index 1cd6177cca..a401a37d99 100644
--- a/TSRM/TSRM.h
+++ b/TSRM/TSRM.h
@@ -100,9 +100,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);
@@ -137,6 +134,7 @@ TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler);
TSRM_API void *tsrm_get_ls_cache(void);
TSRM_API size_t tsrm_get_ls_cache_tcb_offset(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