@@ -57,6 +57,7 @@ static void php_swoole_thread_register_stdio_file_handles(bool no_close);
57
57
58
58
static thread_local zval thread_argv = {};
59
59
static thread_local JMP_BUF *thread_bailout = nullptr ;
60
+ static std::atomic<size_t > thread_num (1 );
60
61
61
62
static sw_inline ThreadObject *thread_fetch_object (zend_object *obj) {
62
63
return (ThreadObject *) ((char *) obj - swoole_thread_handlers.offset );
@@ -103,6 +104,7 @@ static const zend_function_entry swoole_thread_methods[] = {
103
104
PHP_ME (swoole_thread, getArguments, arginfo_class_Swoole_Thread_getArguments, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
104
105
PHP_ME (swoole_thread, getId, arginfo_class_Swoole_Thread_getId, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
105
106
PHP_ME (swoole_thread, getTsrmInfo, arginfo_class_Swoole_Thread_getTsrmInfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
107
+ PHP_MALIAS (swoole_thread, info, getTsrmInfo, arginfo_class_Swoole_Thread_getTsrmInfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
106
108
PHP_FE_END
107
109
};
108
110
// clang-format on
@@ -245,15 +247,20 @@ void php_swoole_thread_rinit() {
245
247
246
248
void php_swoole_thread_rshutdown () {
247
249
zval_dtor (&thread_argv);
248
- if (tsrm_is_main_thread ()) {
249
- if (request_info.path_translated ) {
250
- free ((void *) request_info.path_translated );
251
- request_info.path_translated = nullptr ;
252
- }
253
- if (request_info.argv_serialized ) {
254
- zend_string_release (request_info.argv_serialized );
255
- request_info.argv_serialized = nullptr ;
256
- }
250
+ if (!tsrm_is_main_thread ()) {
251
+ return ;
252
+ }
253
+ if (thread_num.load () > 1 ) {
254
+ swoole_warning (" Fatal Error: %zu active threads are running, cannot exit safely." , thread_num.load ());
255
+ exit (200 );
256
+ }
257
+ if (request_info.path_translated ) {
258
+ free ((void *) request_info.path_translated );
259
+ request_info.path_translated = nullptr ;
260
+ }
261
+ if (request_info.argv_serialized ) {
262
+ zend_string_release (request_info.argv_serialized );
263
+ request_info.argv_serialized = nullptr ;
257
264
}
258
265
}
259
266
@@ -297,6 +304,7 @@ static void php_swoole_thread_register_stdio_file_handles(bool no_close) {
297
304
}
298
305
299
306
void php_swoole_thread_start (zend_string *file, ZendArray *argv) {
307
+ thread_num.fetch_add (1 );
300
308
ts_resource (0 );
301
309
#if defined(COMPILE_DL_SWOOLE) && defined(ZTS)
302
310
ZEND_TSRMLS_CACHE_UPDATE ();
@@ -355,6 +363,7 @@ void php_swoole_thread_start(zend_string *file, ZendArray *argv) {
355
363
zend_string_release (file);
356
364
ts_free_thread ();
357
365
swoole_thread_clean ();
366
+ thread_num.fetch_sub (1 );
358
367
}
359
368
360
369
void php_swoole_thread_bailout (void ) {
@@ -426,6 +435,7 @@ static PHP_METHOD(swoole_thread, getTsrmInfo) {
426
435
add_assoc_bool (return_value, " is_main_thread" , tsrm_is_main_thread ());
427
436
add_assoc_bool (return_value, " is_shutdown" , tsrm_is_shutdown ());
428
437
add_assoc_string (return_value, " api_name" , tsrm_api_name ());
438
+ add_assoc_long (return_value, " thread_num" , thread_num.load ());
429
439
}
430
440
431
441
#define CAST_OBJ_TO_RESOURCE (_name, _type ) \
0 commit comments