summaryrefslogtreecommitdiff
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
parent0504f045914a7bdef6905f54167fb9722a5de7e2 (diff)
parent68485f8ab4df0e1b3e4f446006ce25b6be358975 (diff)
downloadphp-git-b98cd0719a51904c1d3813cb7926494ea7623a92.tar.gz
Merge branch 'PHP-7.4'
* PHP-7.4: implement tsrm_is_shutdown API
-rw-r--r--TSRM/TSRM.c119
-rw-r--r--TSRM/TSRM.h4
-rw-r--r--Zend/zend_signal.c11
-rw-r--r--main/main.c4
-rw-r--r--sapi/phpdbg/phpdbg.c4
5 files changed, 52 insertions, 90 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
diff --git a/Zend/zend_signal.c b/Zend/zend_signal.c
index 3e9fd227ac..703097eeb5 100644
--- a/Zend/zend_signal.c
+++ b/Zend/zend_signal.c
@@ -82,16 +82,17 @@ void zend_signal_handler_defer(int signo, siginfo_t *siginfo, void *context)
{
int errno_save = errno;
zend_signal_queue_t *queue, *qtmp;
- zend_bool is_handling_safe = 1;
#ifdef ZTS
/* A signal could hit after TSRM shutdown, in this case globals are already freed. */
- if (NULL == TSRMLS_CACHE || NULL == TSRMG_BULK_STATIC(zend_signal_globals_id, zend_signal_globals_t *)) {
- is_handling_safe = 0;
+ if (tsrm_is_shutdown()) {
+ /* Forward to default handler handler */
+ zend_signal_handler(signo, siginfo, context);
+ return;
}
#endif
- if (EXPECTED(is_handling_safe && SIGG(active))) {
+ if (EXPECTED(SIGG(active))) {
if (UNEXPECTED(SIGG(depth) == 0)) { /* try to handle signal */
if (UNEXPECTED(SIGG(blocked))) {
SIGG(blocked) = 0;
@@ -176,7 +177,7 @@ static void zend_signal_handler(int signo, siginfo_t *siginfo, void *context)
sigset_t sigset;
zend_signal_entry_t p_sig;
#ifdef ZTS
- if (NULL == TSRMLS_CACHE || NULL == TSRMG_BULK_STATIC(zend_signal_globals_id, zend_signal_globals_t *)) {
+ if (tsrm_is_shutdown()) {
p_sig.flags = 0;
p_sig.handler = SIG_DFL;
} else
diff --git a/main/main.c b/main/main.c
index b6cafb5dff..43144f50a2 100644
--- a/main/main.c
+++ b/main/main.c
@@ -2488,10 +2488,6 @@ void php_module_shutdown(void)
zend_interned_strings_switch_storage(0);
-#ifdef ZTS
- ts_free_worker_threads();
-#endif
-
#if ZEND_RC_DEBUG
zend_rc_debug = 0;
#endif
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c
index eca24b4a4d..463749ea3a 100644
--- a/sapi/phpdbg/phpdbg.c
+++ b/sapi/phpdbg/phpdbg.c
@@ -2161,8 +2161,6 @@ phpdbg_out:
Z_PTR_P(zv) = (void*)PHPDBG_G(orig_url_wrap_php);
}
- php_module_shutdown();
-
#ifndef _WIN32
/* force override (no zend_signals) to prevent crashes due to signal recursion in SIGSEGV/SIGBUS handlers */
signal(SIGSEGV, SIG_DFL);
@@ -2173,6 +2171,8 @@ phpdbg_out:
#endif
}
+ php_module_shutdown();
+
sapi_shutdown();
if (sapi_name) {