Skip to content

Commit d204def

Browse files
committed
Added Thread::isAlive()
1 parent 5ad750f commit d204def

File tree

5 files changed

+56
-4
lines changed

5 files changed

+56
-4
lines changed

ext-src/stubs/php_swoole_thread.stub.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public function __construct(string $script_file, mixed ...$args) {}
77
public function join(): bool {}
88
public function joinable(): bool {}
99
public function getExitStatus(): int {}
10+
public function isAlive(): bool {}
1011
public function detach(): bool {}
1112

1213
public static function getArguments(): ?array {}

ext-src/stubs/php_swoole_thread_arginfo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: d1d1e5d35cfda110527408faf9376dda24680c7f */
2+
* Stub hash: 1a0aa05d8165c567920a234da0801c3231f38588 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread___construct, 0, 0, 1)
55
ZEND_ARG_TYPE_INFO(0, script_file, IS_STRING, 0)
@@ -14,6 +14,8 @@ ZEND_END_ARG_INFO()
1414
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_getExitStatus, 0, 0, IS_LONG, 0)
1515
ZEND_END_ARG_INFO()
1616

17+
#define arginfo_class_Swoole_Thread_isAlive arginfo_class_Swoole_Thread_join
18+
1719
#define arginfo_class_Swoole_Thread_detach arginfo_class_Swoole_Thread_join
1820

1921
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_getArguments, 0, 0, IS_ARRAY, 1)

ext-src/swoole_thread.cc

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ typedef std::thread Thread;
4949

5050
struct ThreadObject {
5151
Thread *thread;
52+
pthread_t thread_id;
5253
zend_object std;
5354
};
5455

@@ -58,6 +59,7 @@ static thread_local zval thread_argv = {};
5859
static thread_local JMP_BUF *thread_bailout = nullptr;
5960
static std::atomic<size_t> thread_num(1);
6061
static zend::ConcurrencyHashMap<pthread_t, int> thread_exit_status(-1);
62+
static zend::ConcurrencyHashMap<pthread_t, bool> thread_living(false);
6163

6264
static sw_inline ThreadObject *thread_fetch_object(zend_object *obj) {
6365
return (ThreadObject *) ((char *) obj - swoole_thread_handlers.offset);
@@ -77,14 +79,16 @@ static void thread_join(zend_object *object) {
7779
ThreadObject *to = thread_fetch_object(object);
7880
if (to->thread && to->thread->joinable()) {
7981
to->thread->join();
80-
php_swoole_thread_join(to->thread->native_handle());
82+
php_swoole_thread_join(to->thread_id);
8183
delete to->thread;
8284
to->thread = nullptr;
8385
}
8486
}
8587

8688
static void thread_free_object(zend_object *object) {
89+
ThreadObject *to = thread_fetch_object(object);
8790
thread_join(object);
91+
thread_living.del(to->thread_id);
8892
zend_object_std_dtor(object);
8993
}
9094

@@ -98,6 +102,7 @@ static zend_object *thread_create_object(zend_class_entry *ce) {
98102

99103
SW_EXTERN_C_BEGIN
100104
static PHP_METHOD(swoole_thread, __construct);
105+
static PHP_METHOD(swoole_thread, isAlive);
101106
static PHP_METHOD(swoole_thread, join);
102107
static PHP_METHOD(swoole_thread, joinable);
103108
static PHP_METHOD(swoole_thread, getExitStatus);
@@ -118,6 +123,7 @@ SW_EXTERN_C_END
118123
// clang-format off
119124
static const zend_function_entry swoole_thread_methods[] = {
120125
PHP_ME(swoole_thread, __construct, arginfo_class_Swoole_Thread___construct, ZEND_ACC_PUBLIC)
126+
PHP_ME(swoole_thread, isAlive, arginfo_class_Swoole_Thread_isAlive, ZEND_ACC_PUBLIC)
121127
PHP_ME(swoole_thread, join, arginfo_class_Swoole_Thread_join, ZEND_ACC_PUBLIC)
122128
PHP_ME(swoole_thread, joinable, arginfo_class_Swoole_Thread_joinable, ZEND_ACC_PUBLIC)
123129
PHP_ME(swoole_thread, getExitStatus, arginfo_class_Swoole_Thread_getExitStatus, ZEND_ACC_PUBLIC)
@@ -202,8 +208,14 @@ static PHP_METHOD(swoole_thread, __construct) {
202208
zend_throw_exception(swoole_exception_ce, e.what(), SW_ERROR_SYSTEM_CALL_FAIL);
203209
return;
204210
}
205-
zend_update_property_long(
206-
swoole_thread_ce, SW_Z8_OBJ_P(ZEND_THIS), ZEND_STRL("id"), (zend_long) to->thread->native_handle());
211+
212+
to->thread_id = to->thread->native_handle();
213+
zend::object_set(ZEND_THIS, ZEND_STRL("id"), (zend_long) to->thread_id);
214+
}
215+
216+
static PHP_METHOD(swoole_thread, isAlive) {
217+
ThreadObject *to = thread_fetch_object(Z_OBJ_P(ZEND_THIS));
218+
RETURN_BOOL(thread_living.get(to->thread_id));
207219
}
208220

209221
static PHP_METHOD(swoole_thread, join) {
@@ -403,6 +415,7 @@ static void thread_register_stdio_file_handles(bool no_close) {
403415

404416
void php_swoole_thread_start(zend_string *file, ZendArray *argv) {
405417
thread_num.fetch_add(1);
418+
thread_living.set(pthread_self(), true);
406419
ts_resource(0);
407420
#if defined(COMPILE_DL_SWOOLE) && defined(ZTS)
408421
ZEND_TSRMLS_CACHE_UPDATE();
@@ -463,6 +476,7 @@ void php_swoole_thread_start(zend_string *file, ZendArray *argv) {
463476
zend_string_release(file);
464477
ts_free_thread();
465478
swoole_thread_clean();
479+
thread_living.set(pthread_self(), false);
466480
thread_num.fetch_sub(1);
467481
}
468482

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
$us = random_int(100, 200000);
3+
usleep($us);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
swoole_thread: thread status
3+
--SKIPIF--
4+
<?php
5+
require __DIR__ . '/../include/skipif.inc';
6+
skip_if_nts();
7+
?>
8+
--FILE--
9+
<?php
10+
require __DIR__ . '/../include/bootstrap.php';
11+
12+
use Swoole\Thread;
13+
14+
$t1 = new Thread(TESTS_API_PATH . '/swoole_thread/sleep.php');
15+
usleep(10);
16+
Assert::true($t1->joinable());
17+
Assert::true($t1->isAlive());
18+
Assert::true($t1->join());
19+
Assert::false($t1->joinable());
20+
Assert::false($t1->isAlive());
21+
22+
$t2 = new Thread(TESTS_API_PATH . '/swoole_thread/sleep.php');
23+
$t2->detach();
24+
usleep(10);
25+
Assert::false($t2->joinable());
26+
Assert::true($t2->isAlive());
27+
while (Thread::getInfo()['thread_num'] > 1) {
28+
usleep(10);
29+
}
30+
Assert::false($t2->isAlive());
31+
?>
32+
--EXPECT--

0 commit comments

Comments
 (0)