Skip to content

Commit ab91af6

Browse files
committed
fix, optimize code, refactor arraylist/map ctor: Allow array as ctor method parameter
1 parent a61d959 commit ab91af6

11 files changed

+130
-51
lines changed

ext-src/php_swoole_thread.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ extern zend_class_entry *swoole_thread_map_ce;
3636
extern zend_class_entry *swoole_thread_queue_ce;
3737

3838
void php_swoole_thread_start(zend_string *file, ZendArray *argv);
39-
ZendArray *php_swoole_thread_argv_create(zval *zdata);
4039
zend_string *php_swoole_serialize(zval *zdata);
4140
bool php_swoole_unserialize(zend_string *data, zval *zv);
4241
void php_swoole_thread_bailout(void);

ext-src/stubs/php_swoole_thread_arraylist.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
namespace Swoole\Thread {
33
class ArrayList implements ArrayAccess, Countable {
4-
public function __construct() {}
4+
public function __construct(?array $array = null) {}
55
public function offsetGet(mixed $key): mixed {}
66
public function offsetExists(mixed $key): bool {}
77
public function offsetSet(mixed $key, mixed $value): void {}

ext-src/stubs/php_swoole_thread_arraylist_arginfo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 180fa4468e220b852fabc5320f2a463a219f7aa3 */
2+
* Stub hash: 70c2427e37953ac2ceefe4c972cbd8b9845b43ab */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread_ArrayList___construct, 0, 0, 0)
5+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, array, IS_ARRAY, 1, "null")
56
ZEND_END_ARG_INFO()
67

78
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_ArrayList_offsetGet, 0, 1, IS_MIXED, 0)

ext-src/stubs/php_swoole_thread_map.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
namespace Swoole\Thread {
33
class Map implements ArrayAccess, Countable {
4-
public function __construct() {}
4+
public function __construct(?array $array = null) {}
55
public function offsetGet(mixed $key): mixed {}
66
public function offsetExists(mixed $key): bool {}
77
public function offsetSet(mixed $key, mixed $value): void {}

ext-src/stubs/php_swoole_thread_map_arginfo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: e85b15919120073579b1d561326eb1c3e446860a */
2+
* Stub hash: 7001a2953b9babe6ed51b8beed9e8ada7e390429 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread_Map___construct, 0, 0, 0)
5+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, array, IS_ARRAY, 1, "null")
56
ZEND_END_ARG_INFO()
67

78
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Map_offsetGet, 0, 1, IS_MIXED, 0)

ext-src/swoole_server.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2651,13 +2651,16 @@ static PHP_METHOD(swoole_server, start) {
26512651
if (!ZVAL_IS_NULL(&server_object->init_arguments)) {
26522652
zval _thread_argv;
26532653
call_user_function(NULL, NULL, &server_object->init_arguments, &_thread_argv, 0, NULL);
2654-
thread_argv = php_swoole_thread_argv_create(&_thread_argv);
2654+
if (ZVAL_IS_ARRAY(&_thread_argv)) {
2655+
thread_argv = ZendArray::from(Z_ARRVAL(_thread_argv));
2656+
}
26552657
zval_ptr_dtor(&_thread_argv);
26562658
}
26572659

26582660
serv->worker_thread_start = [bootstrap, thread_argv](const WorkerFn &fn) {
26592661
worker_thread_fn = fn;
26602662
zend_string *bootstrap_copy = zend_string_dup(bootstrap, 1);
2663+
thread_argv->add_ref();
26612664
php_swoole_thread_start(bootstrap_copy, thread_argv);
26622665
};
26632666
}
@@ -2674,6 +2677,9 @@ static PHP_METHOD(swoole_server, start) {
26742677
if (bootstrap) {
26752678
zend_string_release(bootstrap);
26762679
}
2680+
if (thread_argv) {
2681+
thread_argv->del_ref();
2682+
}
26772683
#endif
26782684

26792685
RETURN_TRUE;

ext-src/swoole_thread.cc

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ END_EXTERN_C()
3434
zend_class_entry *swoole_thread_ce;
3535
static zend_object_handlers swoole_thread_handlers;
3636

37-
zend_class_entry *swoole_thread_stream_ce;
38-
static zend_object_handlers swoole_thread_stream_handlers;
39-
40-
zend_class_entry *swoole_thread_socket_ce;
41-
static zend_object_handlers swoole_thread_socket_handlers;
42-
4337
static struct {
4438
char *path_translated;
4539
zend_string *argv_serialized;
@@ -63,16 +57,16 @@ static void php_swoole_thread_register_stdio_file_handles(bool no_close);
6357
static thread_local zval thread_argv;
6458
static thread_local JMP_BUF *thread_bailout = nullptr;
6559

66-
static sw_inline ThreadObject *php_swoole_thread_fetch_object(zend_object *obj) {
60+
static sw_inline ThreadObject *thread_fetch_object(zend_object *obj) {
6761
return (ThreadObject *) ((char *) obj - swoole_thread_handlers.offset);
6862
}
6963

70-
static void php_swoole_thread_free_object(zend_object *object) {
64+
static void thread_free_object(zend_object *object) {
7165
php_swoole_thread_join(object);
7266
zend_object_std_dtor(object);
7367
}
7468

75-
static zend_object *php_swoole_thread_create_object(zend_class_entry *ce) {
69+
static zend_object *thread_create_object(zend_class_entry *ce) {
7670
ThreadObject *to = (ThreadObject *) zend_object_alloc(sizeof(ThreadObject), ce);
7771
zend_object_std_init(&to->std, ce);
7872
object_properties_init(&to->std, ce);
@@ -81,7 +75,7 @@ static zend_object *php_swoole_thread_create_object(zend_class_entry *ce) {
8175
}
8276

8377
static void php_swoole_thread_join(zend_object *object) {
84-
ThreadObject *to = php_swoole_thread_fetch_object(object);
78+
ThreadObject *to = thread_fetch_object(object);
8579
if (to->thread && to->thread->joinable()) {
8680
to->thread->join();
8781
delete to->thread;
@@ -118,21 +112,11 @@ void php_swoole_thread_minit(int module_number) {
118112
SW_SET_CLASS_CLONEABLE(swoole_thread, sw_zend_class_clone_deny);
119113
SW_SET_CLASS_UNSET_PROPERTY_HANDLER(swoole_thread, sw_zend_class_unset_property_deny);
120114
SW_SET_CLASS_CUSTOM_OBJECT(
121-
swoole_thread, php_swoole_thread_create_object, php_swoole_thread_free_object, ThreadObject, std);
115+
swoole_thread, thread_create_object, thread_free_object, ThreadObject, std);
122116

123117
zend_declare_property_long(swoole_thread_ce, ZEND_STRL("id"), 0, ZEND_ACC_PUBLIC | ZEND_ACC_READONLY);
124118
zend_declare_class_constant_long(
125119
swoole_thread_ce, ZEND_STRL("HARDWARE_CONCURRENCY"), std::thread::hardware_concurrency());
126-
127-
// only used for thread argument forwarding
128-
SW_INIT_CLASS_ENTRY_DATA_OBJECT(swoole_thread_stream, "Swoole\\Thread\\Stream");
129-
zend_declare_property_long(swoole_thread_stream_ce, ZEND_STRL("fd"), 0, ZEND_ACC_PUBLIC | ZEND_ACC_READONLY);
130-
131-
SW_INIT_CLASS_ENTRY_DATA_OBJECT(swoole_thread_socket, "Swoole\\Thread\\Socket");
132-
zend_declare_property_long(swoole_thread_socket_ce, ZEND_STRL("fd"), 0, ZEND_ACC_PUBLIC | ZEND_ACC_READONLY);
133-
zend_declare_property_long(swoole_thread_socket_ce, ZEND_STRL("domain"), 0, ZEND_ACC_PUBLIC | ZEND_ACC_READONLY);
134-
zend_declare_property_long(swoole_thread_socket_ce, ZEND_STRL("type"), 0, ZEND_ACC_PUBLIC | ZEND_ACC_READONLY);
135-
zend_declare_property_long(swoole_thread_socket_ce, ZEND_STRL("protocol"), 0, ZEND_ACC_PUBLIC | ZEND_ACC_READONLY);
136120
}
137121

138122
static PHP_METHOD(swoole_thread, __construct) {
@@ -152,7 +136,7 @@ static PHP_METHOD(swoole_thread, __construct) {
152136
return;
153137
}
154138

155-
ThreadObject *to = php_swoole_thread_fetch_object(Z_OBJ_P(ZEND_THIS));
139+
ThreadObject *to = thread_fetch_object(Z_OBJ_P(ZEND_THIS));
156140
zend_string *file = zend_string_init(script_file, l_script_file, 1);
157141

158142
if (argc > 0) {
@@ -173,7 +157,7 @@ static PHP_METHOD(swoole_thread, __construct) {
173157
}
174158

175159
static PHP_METHOD(swoole_thread, join) {
176-
ThreadObject *to = php_swoole_thread_fetch_object(Z_OBJ_P(ZEND_THIS));
160+
ThreadObject *to = thread_fetch_object(Z_OBJ_P(ZEND_THIS));
177161
if (!to || !to->thread || !to->thread->joinable()) {
178162
RETURN_FALSE;
179163
}
@@ -182,15 +166,15 @@ static PHP_METHOD(swoole_thread, join) {
182166
}
183167

184168
static PHP_METHOD(swoole_thread, joinable) {
185-
ThreadObject *to = php_swoole_thread_fetch_object(Z_OBJ_P(ZEND_THIS));
169+
ThreadObject *to = thread_fetch_object(Z_OBJ_P(ZEND_THIS));
186170
if (to == nullptr || !to->thread) {
187171
RETURN_FALSE;
188172
}
189173
RETURN_BOOL(to->thread->joinable());
190174
}
191175

192176
static PHP_METHOD(swoole_thread, detach) {
193-
ThreadObject *to = php_swoole_thread_fetch_object(Z_OBJ_P(ZEND_THIS));
177+
ThreadObject *to = thread_fetch_object(Z_OBJ_P(ZEND_THIS));
194178
if (to == nullptr || !to->thread) {
195179
RETURN_FALSE;
196180
}
@@ -208,22 +192,6 @@ static PHP_METHOD(swoole_thread, getId) {
208192
RETURN_LONG((zend_long) pthread_self());
209193
}
210194

211-
ZendArray *php_swoole_thread_argv_create(zval *zdata) {
212-
if (!ZVAL_IS_ARRAY(zdata)) {
213-
return nullptr;
214-
}
215-
216-
auto array = new ZendArray();
217-
zval *elem;
218-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zdata), elem) {
219-
ZVAL_DEREF(elem);
220-
array->append(elem);
221-
}
222-
ZEND_HASH_FOREACH_END();
223-
224-
return array;
225-
}
226-
227195
zend_string *php_swoole_serialize(zval *zdata) {
228196
php_serialize_data_t var_hash;
229197
smart_str serialized_data = {0};
@@ -366,7 +334,7 @@ void php_swoole_thread_start(zend_string *file, ZendArray *argv) {
366334
}
367335
if (argv) {
368336
argv->toArray(&thread_argv);
369-
delete argv;
337+
argv->del_ref();
370338
}
371339
php_swoole_thread_register_stdio_file_handles(true);
372340
php_execute_script(&file_handle);
@@ -810,6 +778,7 @@ ZendArray *ZendArray::from(zend_array *src) {
810778
zval *tmp;
811779
ZendArray *result = new ZendArray();
812780
ZEND_HASH_FOREACH_KEY_VAL(src, index, key, tmp) {
781+
ZVAL_DEREF(tmp);
813782
if (key) {
814783
result->add(key, tmp);
815784
} else {

ext-src/swoole_thread_arraylist.cc

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,27 @@ void php_swoole_thread_arraylist_minit(int module_number) {
116116
}
117117

118118
static PHP_METHOD(swoole_thread_arraylist, __construct) {
119-
ZEND_PARSE_PARAMETERS_NONE();
119+
zend_array *array = nullptr;
120+
ZEND_PARSE_PARAMETERS_START(0, 1)
121+
Z_PARAM_OPTIONAL
122+
Z_PARAM_ARRAY_HT_OR_NULL(array)
123+
ZEND_PARSE_PARAMETERS_END();
120124

121125
auto ao = arraylist_fetch_object(Z_OBJ_P(ZEND_THIS));
122126
if (ao->list != nullptr) {
123127
zend_throw_error(NULL, "Constructor of %s can only be called once", SW_Z_OBJCE_NAME_VAL_P(ZEND_THIS));
124128
return;
125129
}
126-
ao->list = new ZendArray();
130+
131+
if (array) {
132+
if (!zend_array_is_list(array)) {
133+
zend_throw_error(NULL, "the parameter $array must be an array of type list");
134+
return;
135+
}
136+
ao->list = ZendArray::from(array);
137+
} else {
138+
ao->list = new ZendArray();
139+
}
127140
}
128141

129142
static PHP_METHOD(swoole_thread_arraylist, offsetGet) {

ext-src/swoole_thread_map.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,23 @@ void php_swoole_thread_map_minit(int module_number) {
118118
}
119119

120120
static PHP_METHOD(swoole_thread_map, __construct) {
121+
zend_array *array = nullptr;
122+
ZEND_PARSE_PARAMETERS_START(0, 1)
123+
Z_PARAM_OPTIONAL
124+
Z_PARAM_ARRAY_HT_OR_NULL(array)
125+
ZEND_PARSE_PARAMETERS_END();
126+
121127
auto mo = map_fetch_object(Z_OBJ_P(ZEND_THIS));
122128
if (mo->map != nullptr) {
123129
zend_throw_error(NULL, "Constructor of %s can only be called once", SW_Z_OBJCE_NAME_VAL_P(ZEND_THIS));
124130
return;
125131
}
126-
mo->map = new ZendArray();
132+
133+
if (array) {
134+
mo->map = ZendArray::from(array);
135+
} else {
136+
mo->map = new ZendArray();
137+
}
127138
}
128139

129140
#define ZEND_ARRAY_CALL_METHOD(array, method, zkey, ...) \

tests/swoole_thread/arraylist.phpt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
swoole_thread: arraylist
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\ArrayList;
13+
14+
$array = [
15+
random_int(1, 999999999999999999),
16+
random_bytes(128),
17+
uniqid(),
18+
time(),
19+
];
20+
21+
$l = new ArrayList($array);
22+
Assert::eq($l->toArray(), $array);
23+
24+
for ($i = 0; $i < count($array); $i++) {
25+
Assert::eq($l[$i], $array[$i]);
26+
}
27+
28+
$array2 = [
29+
'key' => 'value',
30+
'hello' => 'world',
31+
];
32+
$l[] = $array2;
33+
34+
Assert::eq($l[4]->toArray(), $array2);
35+
36+
try {
37+
$l2 = new ArrayList($array2);
38+
echo "never here\n";
39+
} catch (Throwable $e) {
40+
Assert::contains($e->getMessage(), 'must be an array of type list');
41+
}
42+
?>
43+
--EXPECTF--

tests/swoole_thread/map.phpt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
swoole_thread: map
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\Map;
13+
14+
$array = [
15+
'a' => random_int(1, 999999999999999999),
16+
'b' => random_bytes(128),
17+
'c' => uniqid(),
18+
'd' => time(),
19+
];
20+
21+
$m = new Map($array);
22+
Assert::eq($m->toArray(), $array);
23+
24+
foreach ($array as $k => $v) {
25+
Assert::eq($m[$k], $array[$k]);
26+
}
27+
28+
$array2 = [
29+
'key' => 'value',
30+
'hello' => 'world',
31+
];
32+
$m['map'] = $array2;
33+
34+
Assert::eq($m['map']->toArray(), $array2);
35+
?>
36+
--EXPECTF--

0 commit comments

Comments
 (0)