Skip to content

Commit 6e9966c

Browse files
authored
Refactor thread resource (#5393)
* Refactor thread resource * fix * fix, optimize code, refactor arraylist/map ctor: Allow array as ctor method parameter * fix tests * Prohibit constructing objects on the stack * Fix tests * optimize code, fix tests * fix tests * Added Map::values() * Change the return value type of Thread:: getArguments() to return null in the main thread * Fix tests
1 parent cd3b627 commit 6e9966c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+812
-653
lines changed

examples/thread/nested_map.php

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
$map = new Swoole\Thread\Map();
3+
4+
$map['map1'] = new Swoole\Thread\Map();
5+
$map['list1'] = new Swoole\Thread\ArrayList();
6+
7+
$map['map1']['key1'] = 'value1';
8+
$map['list1'][0] = 'value2';
9+
$map['str'] = 'hello world';
10+
11+
$map['map2'] = [
12+
'a' => uniqid(),
13+
'b' => random_int(1000, 9999),
14+
];
15+
16+
var_dump($map['map1']['key1']);
17+
var_dump($map['list1'][0]);
18+
19+
var_dump($map['list1']->toArray());
20+
21+
var_dump($map['map2']);

ext-src/php_swoole_cxx.h

+4
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,10 @@ static inline void object_set(zval *obj, const char *name, size_t l_name, const
670670
zend_update_property_string(Z_OBJCE_P(obj), Z_OBJ_P(obj), name, l_name, value);
671671
}
672672

673+
static inline void object_set(zval *obj, const char *name, size_t l_name, zend_long value) {
674+
zend_update_property_long(Z_OBJCE_P(obj), Z_OBJ_P(obj), name, l_name, value);
675+
}
676+
673677
static inline zval *object_get(zval *obj, const char *name, size_t l_name) {
674678
static zval rv;
675679
return zend_read_property(Z_OBJCE_P(obj), Z_OBJ_P(obj), name, l_name, 1, &rv);

ext-src/php_swoole_thread.h

+81-17
Original file line numberDiff line numberDiff line change
@@ -25,44 +25,81 @@
2525

2626
typedef uint32_t ThreadResourceId;
2727
struct ThreadResource;
28-
29-
ThreadResourceId php_swoole_thread_resource_insert(ThreadResource *res);
30-
bool php_swoole_thread_resource_free(ThreadResourceId resource_id, ThreadResource *res);
31-
ThreadResource *php_swoole_thread_resource_fetch(ThreadResourceId resource_id);
32-
33-
void php_swoole_thread_start(zend_string *file, zend_string *argv);
34-
zend_string *php_swoole_thread_argv_serialize(zval *zdata);
35-
bool php_swoole_thread_argv_unserialize(zend_string *data, zval *zv);
28+
struct ZendArray;
29+
30+
extern zend_class_entry *swoole_thread_ce;
31+
extern zend_class_entry *swoole_thread_error_ce;
32+
extern zend_class_entry *swoole_thread_arraylist_ce;
33+
extern zend_class_entry *swoole_thread_atomic_ce;
34+
extern zend_class_entry *swoole_thread_atomic_long_ce;
35+
extern zend_class_entry *swoole_thread_barrier_ce;
36+
extern zend_class_entry *swoole_thread_lock_ce;
37+
extern zend_class_entry *swoole_thread_map_ce;
38+
extern zend_class_entry *swoole_thread_queue_ce;
39+
40+
void php_swoole_thread_start(zend_string *file, ZendArray *argv);
3641
zend_string *php_swoole_serialize(zval *zdata);
3742
bool php_swoole_unserialize(zend_string *data, zval *zv);
38-
void php_swoole_thread_argv_clean(zval *zdata);
3943
void php_swoole_thread_bailout(void);
4044

41-
zval *php_swoole_thread_get_arguments();
45+
ThreadResource *php_swoole_thread_arraylist_cast(zval *zobject);
46+
ThreadResource *php_swoole_thread_map_cast(zval *zobject);
47+
ThreadResource *php_swoole_thread_queue_cast(zval *zobject);
48+
ThreadResource *php_swoole_thread_lock_cast(zval *zobject);
49+
ThreadResource *php_swoole_thread_atomic_cast(zval *zobject);
50+
ThreadResource *php_swoole_thread_atomic_long_cast(zval *zobject);
51+
ThreadResource *php_swoole_thread_barrier_cast(zval *zobject);
52+
53+
void php_swoole_thread_arraylist_create(zval *return_value, ThreadResource *resource);
54+
void php_swoole_thread_map_create(zval *return_value, ThreadResource *resource);
55+
void php_swoole_thread_queue_create(zval *return_value, ThreadResource *resource);
56+
void php_swoole_thread_lock_create(zval *return_value, ThreadResource *resource);
57+
void php_swoole_thread_atomic_create(zval *return_value, ThreadResource *resource);
58+
void php_swoole_thread_atomic_long_create(zval *return_value, ThreadResource *resource);
59+
void php_swoole_thread_barrier_create(zval *return_value, ThreadResource *resource);
60+
61+
int php_swoole_thread_stream_cast(zval *zstream);
62+
void php_swoole_thread_stream_create(zval *return_value, zend_long sockfd);
63+
64+
int php_swoole_thread_co_socket_cast(zval *zstream, swSocketType *type);
65+
void php_swoole_thread_co_socket_create(zval *return_value, zend_long sockfd, swSocketType type);
4266

4367
#define EMSG_NO_RESOURCE "resource not found"
4468
#define ECODE_NO_RESOURCE -2
4569

4670
enum {
71+
IS_ARRAYLIST = 80,
72+
IS_QUEUE = 81,
73+
IS_LOCK = 82,
74+
IS_MAP = 83,
75+
IS_BARRIER = 84,
76+
IS_ATOMIC = 85,
77+
IS_ATOMIC_LONG = 86,
4778
IS_CO_SOCKET = 97,
4879
IS_STREAM_SOCKET = 98,
4980
IS_SERIALIZED_OBJECT = 99,
5081
};
5182

52-
struct ThreadResource {
53-
uint32_t ref_count;
83+
class ThreadResource {
84+
sw_atomic_t ref_count;
5485

86+
public:
5587
ThreadResource() {
5688
ref_count = 1;
5789
}
5890

59-
uint32_t add_ref() {
60-
return ++ref_count;
91+
void add_ref() {
92+
sw_atomic_add_fetch(&ref_count, 1);
6193
}
6294

63-
uint32_t del_ref() {
64-
return --ref_count;
95+
void del_ref() {
96+
if (sw_atomic_sub_fetch(&ref_count, 1) == 0) {
97+
delete this;
98+
}
6599
}
100+
101+
protected:
102+
virtual ~ThreadResource() {}
66103
};
67104

68105
struct ArrayItem {
@@ -77,6 +114,7 @@ struct ArrayItem {
77114
swSocketType type;
78115
} socket;
79116
zend_string *serialized_object;
117+
ThreadResource *resource;
80118
} value;
81119

82120
ArrayItem(zval *zvalue) {
@@ -88,6 +126,10 @@ struct ArrayItem {
88126
key = zend_string_init(_key.val(), _key.len(), 1);
89127
}
90128

129+
void setKey(zend_string *_key) {
130+
key = zend_string_init(ZSTR_VAL(_key), ZSTR_LEN(_key), 1);
131+
}
132+
91133
void store(zval *zvalue);
92134
void fetch(zval *return_value);
93135
void release();
@@ -115,7 +157,7 @@ struct ZendArray : ThreadResource {
115157
zend_hash_init(&ht, 0, NULL, item_dtor, 1);
116158
}
117159

118-
~ZendArray() {
160+
~ZendArray() override {
119161
zend_hash_destroy(&ht);
120162
}
121163

@@ -125,6 +167,25 @@ struct ZendArray : ThreadResource {
125167
lock_.unlock();
126168
}
127169

170+
void append(zval *zvalue);
171+
172+
void add(zend_string *skey, zval *zvalue) {
173+
auto item = new ArrayItem(zvalue);
174+
item->setKey(skey);
175+
zend_hash_add_ptr(&ht, item->key, item);
176+
}
177+
178+
void add(zend::String &skey, zval *zvalue) {
179+
auto item = new ArrayItem(zvalue);
180+
item->setKey(skey);
181+
zend_hash_add_ptr(&ht, item->key, item);
182+
}
183+
184+
void add(zend_long index, zval *zvalue) {
185+
auto item = new ArrayItem(zvalue);
186+
zend_hash_index_add_ptr(&ht, index, item);
187+
}
188+
128189
bool index_exists(zend_long index) {
129190
return index < (zend_long) zend_hash_num_elements(&ht);
130191
}
@@ -189,6 +250,8 @@ struct ZendArray : ThreadResource {
189250
}
190251

191252
void keys(zval *return_value);
253+
void values(zval *return_value);
254+
void toArray(zval *return_value);
192255

193256
void intkey_offsetGet(zend_long index, zval *return_value) {
194257
lock_.lock_rd();
@@ -251,6 +314,7 @@ struct ZendArray : ThreadResource {
251314

252315
static void incr_update(ArrayItem *item, zval *zvalue, zval *return_value);
253316
static ArrayItem *incr_create(zval *zvalue, zval *return_value);
317+
static ZendArray *from(zend_array *ht);
254318
};
255319

256320
#define INIT_ARRAY_INCR_PARAMS \

ext-src/stubs/php_swoole_thread.stub.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public function join(): bool {}
88
public function joinable(): bool {}
99
public function detach(): bool {}
1010

11-
public static function getArguments(): array {}
11+
public static function getArguments(): ?array {}
1212
public static function getId(): int {}
1313
public static function getTsrmInfo(): array {}
1414
}

ext-src/stubs/php_swoole_thread_arginfo.h

+4-3
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: 234aeadaab2ab31facf1909f0e3027e433f2a88f */
2+
* Stub hash: 261ac9fd29d4f2f37118ff3b96428a0b2f85223a */
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)
@@ -13,10 +13,11 @@ ZEND_END_ARG_INFO()
1313

1414
#define arginfo_class_Swoole_Thread_detach arginfo_class_Swoole_Thread_join
1515

16-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_getArguments, 0, 0, IS_ARRAY, 0)
16+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_getArguments, 0, 0, IS_ARRAY, 1)
1717
ZEND_END_ARG_INFO()
1818

1919
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_getId, 0, 0, IS_LONG, 0)
2020
ZEND_END_ARG_INFO()
2121

22-
#define arginfo_class_Swoole_Thread_getTsrmInfo arginfo_class_Swoole_Thread_getArguments
22+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_getTsrmInfo, 0, 0, IS_ARRAY, 0)
23+
ZEND_END_ARG_INFO()
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 {}
@@ -10,6 +10,6 @@ public function count(): int {}
1010
public function incr(mixed $key, mixed $value = 1): mixed {}
1111
public function decr(mixed $key, mixed $value = 1): mixed {}
1212
public function clean(): void {}
13-
public function __wakeup(): void {}
13+
public function toArray(): array {}
1414
}
1515
}

ext-src/stubs/php_swoole_thread_arraylist_arginfo.h

+4-2
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: 366fd5114ee7fab588f8c004cd08f600918d3394 */
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)
@@ -34,4 +35,5 @@ ZEND_END_ARG_INFO()
3435
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_ArrayList_clean, 0, 0, IS_VOID, 0)
3536
ZEND_END_ARG_INFO()
3637

37-
#define arginfo_class_Swoole_Thread_ArrayList___wakeup arginfo_class_Swoole_Thread_ArrayList_clean
38+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_ArrayList_toArray, 0, 0, IS_ARRAY, 0)
39+
ZEND_END_ARG_INFO()

ext-src/stubs/php_swoole_thread_atomic.stub.php

-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ public function set(int $value): void {}
99
public function cmpset(int $cmp_value, int $new_value): bool {}
1010
public function wait(float $timeout = 1.0): bool {}
1111
public function wakeup(int $count = 1): bool {}
12-
public function __wakeup(): void {}
1312
}
1413
}
1514

@@ -21,6 +20,5 @@ public function sub(int $sub_value = 1): int {}
2120
public function get(): int {}
2221
public function set(int $value): void {}
2322
public function cmpset(int $cmp_value, int $new_value): bool {}
24-
public function __wakeup(): void {}
2523
}
2624
}

ext-src/stubs/php_swoole_thread_atomic_arginfo.h

+1-6
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: c27562c58b557e8e211bbf52859e4e9818c35f55 */
2+
* Stub hash: 4b6cbceb50641f6204da9caed8c514a526c57ee8 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread_Atomic___construct, 0, 0, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_LONG, 0, "0")
@@ -33,9 +33,6 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Atomic_wakeu
3333
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, count, IS_LONG, 0, "1")
3434
ZEND_END_ARG_INFO()
3535

36-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Atomic___wakeup, 0, 0, IS_VOID, 0)
37-
ZEND_END_ARG_INFO()
38-
3936
#define arginfo_class_Swoole_Thread_Atomic_Long___construct arginfo_class_Swoole_Thread_Atomic___construct
4037

4138
#define arginfo_class_Swoole_Thread_Atomic_Long_add arginfo_class_Swoole_Thread_Atomic_add
@@ -47,5 +44,3 @@ ZEND_END_ARG_INFO()
4744
#define arginfo_class_Swoole_Thread_Atomic_Long_set arginfo_class_Swoole_Thread_Atomic_set
4845

4946
#define arginfo_class_Swoole_Thread_Atomic_Long_cmpset arginfo_class_Swoole_Thread_Atomic_cmpset
50-
51-
#define arginfo_class_Swoole_Thread_Atomic_Long___wakeup arginfo_class_Swoole_Thread_Atomic___wakeup

ext-src/stubs/php_swoole_thread_barrier.stub.php

-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,5 @@
33
class Barrier {
44
public function __construct(int $count) {}
55
public function wait(): void {}
6-
public function __wakeup(): void {}
76
}
87
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: eac62993bfb3fbd87587a8e6997c16bca7dc5dbc */
2+
* Stub hash: 1fe9f55b0b9487e9cd469dcd215acee893254a04 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread_Barrier___construct, 0, 0, 1)
55
ZEND_ARG_TYPE_INFO(0, count, IS_LONG, 0)
66
ZEND_END_ARG_INFO()
77

88
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Barrier_wait, 0, 0, IS_VOID, 0)
99
ZEND_END_ARG_INFO()
10-
11-
#define arginfo_class_Swoole_Thread_Barrier___wakeup arginfo_class_Swoole_Thread_Barrier_wait

ext-src/stubs/php_swoole_thread_lock.stub.php

-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,5 @@ public function trylock(): bool {}
99
public function lock_read(): bool {}
1010
public function trylock_read(): bool {}
1111
public function unlock(): bool {}
12-
public function __wakeup(): void {}
1312
}
1413
}

ext-src/stubs/php_swoole_thread_lock_arginfo.h

+1-4
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: e8d4c9f0d13a62fd6a0d67838b26cb4451f89ee9 */
2+
* Stub hash: 3c5cd43d34f7669ed8144417b6b36dbc43fb4392 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread_Lock___construct, 0, 0, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_LONG, 0, "SWOOLE_MUTEX")
@@ -22,6 +22,3 @@ ZEND_END_ARG_INFO()
2222
#define arginfo_class_Swoole_Thread_Lock_trylock_read arginfo_class_Swoole_Thread_Lock_lock
2323

2424
#define arginfo_class_Swoole_Thread_Lock_unlock arginfo_class_Swoole_Thread_Lock_lock
25-
26-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Lock___wakeup, 0, 0, IS_VOID, 0)
27-
ZEND_END_ARG_INFO()
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
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 {}
88
public function offsetUnset(mixed $key): void {}
99
public function count(): int {}
1010
public function keys(): array {}
11+
public function values(): array {}
1112
public function incr(mixed $key, mixed $value = 1): mixed {}
1213
public function decr(mixed $key, mixed $value = 1): mixed {}
1314
public function add(mixed $key, mixed $value): bool {}
1415
public function update(mixed $key, mixed $value): bool {}
1516
public function clean(): void {}
16-
public function __wakeup(): void {}
17+
public function toArray(): array {}
1718
}
1819
}

ext-src/stubs/php_swoole_thread_map_arginfo.h

+5-2
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: 44e8467dc5e0e3cc91e46840d4a1ae686ee6c0a6 */
2+
* Stub hash: 40e24b68b9e9d7f7192a8f91e4b31b3020e9faca */
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)
@@ -27,6 +28,8 @@ ZEND_END_ARG_INFO()
2728
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Map_keys, 0, 0, IS_ARRAY, 0)
2829
ZEND_END_ARG_INFO()
2930

31+
#define arginfo_class_Swoole_Thread_Map_values arginfo_class_Swoole_Thread_Map_keys
32+
3033
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Map_incr, 0, 1, IS_MIXED, 0)
3134
ZEND_ARG_TYPE_INFO(0, key, IS_MIXED, 0)
3235
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_MIXED, 0, "1")
@@ -44,4 +47,4 @@ ZEND_END_ARG_INFO()
4447
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Map_clean, 0, 0, IS_VOID, 0)
4548
ZEND_END_ARG_INFO()
4649

47-
#define arginfo_class_Swoole_Thread_Map___wakeup arginfo_class_Swoole_Thread_Map_clean
50+
#define arginfo_class_Swoole_Thread_Map_toArray arginfo_class_Swoole_Thread_Map_keys

ext-src/stubs/php_swoole_thread_queue.stub.php

-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@ public function push(mixed $value, int $notify_which = 0): void {}
66
public function pop(float $wait = 0): mixed {}
77
public function count(): int {}
88
public function clean(): void {}
9-
public function __wakeup(): void {}
109
}
1110
}

0 commit comments

Comments
 (0)