]> granicus.if.org Git - php/commitdiff
implement tsrm_is_shutdown API
authorJoe Watkins <krakjoe@php.net>
Wed, 26 Jun 2019 11:18:50 +0000 (13:18 +0200)
committerJoe Watkins <krakjoe@php.net>
Fri, 28 Jun 2019 08:27:19 +0000 (10:27 +0200)
TSRM/TSRM.c
TSRM/TSRM.h
Zend/zend_signal.c
main/main.c
sapi/phpdbg/phpdbg.c

index 34080eed9627242049f63d140ac96fb948fec27a..1a8d5192ff7ddff1fc7339ee34c2ab5963362ff6 100644 (file)
 #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)
index d2be3184408a8b5541422125f881d9b8f3672c1e..3c88ac3edb332a17948ef4e3d90721335299b062 100644 (file)
@@ -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
index 3e9fd227ac5b3383476551beb2ee9b531eee31af..703097eeb53f0514e36b845feffc3d36cbb6ed18 100644 (file)
@@ -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
index f87d07a192502de6ac7d80f2c738b377a1cac65a..d276528edb2ad884d78a9acf1535a55f6b732aa5 100644 (file)
@@ -2514,10 +2514,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
index eca24b4a4dc97f5974cec562c6a2fda2172f1253..463749ea3acb4f50af1b027015a22214fadf7134 100644 (file)
@@ -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) {