Skip to content

Commit f3a3d9b

Browse files
committed
Refactor thread resource
1 parent 4860011 commit f3a3d9b

30 files changed

+524
-536
lines changed

examples/thread/nested_map.php

Lines changed: 21 additions & 0 deletions
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_thread.h

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,44 +25,73 @@
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_arraylist_ce;
31+
extern zend_class_entry *swoole_thread_atomic_ce;
32+
extern zend_class_entry *swoole_thread_atomic_long_ce;
33+
extern zend_class_entry *swoole_thread_barrier_ce;
34+
extern zend_class_entry *swoole_thread_lock_ce;
35+
extern zend_class_entry *swoole_thread_map_ce;
36+
extern zend_class_entry *swoole_thread_queue_ce;
37+
38+
void php_swoole_thread_start(zend_string *file, ZendArray *argv);
39+
ZendArray *php_swoole_thread_argv_create(zval *zdata);
3640
zend_string *php_swoole_serialize(zval *zdata);
3741
bool php_swoole_unserialize(zend_string *data, zval *zv);
38-
void php_swoole_thread_argv_clean(zval *zdata);
3942
void php_swoole_thread_bailout(void);
4043

41-
zval *php_swoole_thread_get_arguments();
44+
ThreadResource *php_swoole_thread_arraylist_cast(zval *zobject);
45+
ThreadResource *php_swoole_thread_map_cast(zval *zobject);
46+
ThreadResource *php_swoole_thread_queue_cast(zval *zobject);
47+
ThreadResource *php_swoole_thread_lock_cast(zval *zobject);
48+
ThreadResource *php_swoole_thread_atomic_cast(zval *zobject);
49+
ThreadResource *php_swoole_thread_atomic_long_cast(zval *zobject);
50+
ThreadResource *php_swoole_thread_barrier_cast(zval *zobject);
51+
52+
void php_swoole_thread_arraylist_create(zval *return_value, ThreadResource *resource);
53+
void php_swoole_thread_map_create(zval *return_value, ThreadResource *resource);
54+
void php_swoole_thread_queue_create(zval *return_value, ThreadResource *resource);
55+
void php_swoole_thread_lock_create(zval *return_value, ThreadResource *resource);
56+
void php_swoole_thread_atomic_create(zval *return_value, ThreadResource *resource);
57+
void php_swoole_thread_atomic_long_create(zval *return_value, ThreadResource *resource);
58+
void php_swoole_thread_barrier_create(zval *return_value, ThreadResource *resource);
4259

4360
#define EMSG_NO_RESOURCE "resource not found"
4461
#define ECODE_NO_RESOURCE -2
4562

4663
enum {
64+
IS_ARRAYLIST = 80,
65+
IS_QUEUE = 81,
66+
IS_LOCK = 82,
67+
IS_MAP = 83,
68+
IS_BARRIER = 84,
69+
IS_ATOMIC = 85,
70+
IS_ATOMIC_LONG = 86,
4771
IS_CO_SOCKET = 97,
4872
IS_STREAM_SOCKET = 98,
4973
IS_SERIALIZED_OBJECT = 99,
5074
};
5175

52-
struct ThreadResource {
53-
uint32_t ref_count;
76+
class ThreadResource {
77+
sw_atomic_t ref_count;
5478

79+
public:
5580
ThreadResource() {
5681
ref_count = 1;
5782
}
5883

59-
uint32_t add_ref() {
60-
return ++ref_count;
84+
void add_ref() {
85+
sw_atomic_add_fetch(&ref_count, 1);
6186
}
6287

63-
uint32_t del_ref() {
64-
return --ref_count;
88+
void del_ref() {
89+
if (sw_atomic_sub_fetch(&ref_count, 1) == 0) {
90+
delete this;
91+
}
6592
}
93+
94+
virtual ~ThreadResource() {}
6695
};
6796

6897
struct ArrayItem {
@@ -77,6 +106,7 @@ struct ArrayItem {
77106
swSocketType type;
78107
} socket;
79108
zend_string *serialized_object;
109+
ThreadResource *resource;
80110
} value;
81111

82112
ArrayItem(zval *zvalue) {
@@ -88,6 +118,10 @@ struct ArrayItem {
88118
key = zend_string_init(_key.val(), _key.len(), 1);
89119
}
90120

121+
void setKey(zend_string *_key) {
122+
key = zend_string_init(ZSTR_VAL(_key), ZSTR_LEN(_key), 1);
123+
}
124+
91125
void store(zval *zvalue);
92126
void fetch(zval *return_value);
93127
void release();
@@ -115,7 +149,7 @@ struct ZendArray : ThreadResource {
115149
zend_hash_init(&ht, 0, NULL, item_dtor, 1);
116150
}
117151

118-
~ZendArray() {
152+
~ZendArray() override {
119153
zend_hash_destroy(&ht);
120154
}
121155

@@ -125,6 +159,25 @@ struct ZendArray : ThreadResource {
125159
lock_.unlock();
126160
}
127161

162+
void append(zval *zvalue);
163+
164+
void add(zend_string *skey, zval *zvalue) {
165+
auto item = new ArrayItem(zvalue);
166+
item->setKey(skey);
167+
zend_hash_add_ptr(&ht, item->key, item);
168+
}
169+
170+
void add(zend::String &skey, zval *zvalue) {
171+
auto item = new ArrayItem(zvalue);
172+
item->setKey(skey);
173+
zend_hash_add_ptr(&ht, item->key, item);
174+
}
175+
176+
void add(zend_long index, zval *zvalue) {
177+
auto item = new ArrayItem(zvalue);
178+
zend_hash_index_add_ptr(&ht, index, item);
179+
}
180+
128181
bool index_exists(zend_long index) {
129182
return index < (zend_long) zend_hash_num_elements(&ht);
130183
}
@@ -189,6 +242,7 @@ struct ZendArray : ThreadResource {
189242
}
190243

191244
void keys(zval *return_value);
245+
void toArray(zval *return_value);
192246

193247
void intkey_offsetGet(zend_long index, zval *return_value) {
194248
lock_.lock_rd();
@@ -251,6 +305,7 @@ struct ZendArray : ThreadResource {
251305

252306
static void incr_update(ArrayItem *item, zval *zvalue, zval *return_value);
253307
static ArrayItem *incr_create(zval *zvalue, zval *return_value);
308+
static ZendArray *from(zend_array *ht);
254309
};
255310

256311
#define INIT_ARRAY_INCR_PARAMS \

ext-src/stubs/php_swoole_thread_arraylist.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 3 additions & 2 deletions
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: 366fd5114ee7fab588f8c004cd08f600918d3394 */
2+
* Stub hash: 180fa4468e220b852fabc5320f2a463a219f7aa3 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread_ArrayList___construct, 0, 0, 0)
55
ZEND_END_ARG_INFO()
@@ -34,4 +34,5 @@ ZEND_END_ARG_INFO()
3434
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_ArrayList_clean, 0, 0, IS_VOID, 0)
3535
ZEND_END_ARG_INFO()
3636

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

ext-src/stubs/php_swoole_thread_atomic.stub.php

Lines changed: 0 additions & 2 deletions
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

Lines changed: 1 addition & 6 deletions
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

Lines changed: 0 additions & 1 deletion
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
}
Lines changed: 1 addition & 3 deletions
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

Lines changed: 0 additions & 1 deletion
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

Lines changed: 1 addition & 4 deletions
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()

ext-src/stubs/php_swoole_thread_map.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ public function decr(mixed $key, mixed $value = 1): mixed {}
1313
public function add(mixed $key, mixed $value): bool {}
1414
public function update(mixed $key, mixed $value): bool {}
1515
public function clean(): void {}
16-
public function __wakeup(): void {}
16+
public function toArray(): array {}
1717
}
1818
}

ext-src/stubs/php_swoole_thread_map_arginfo.h

Lines changed: 2 additions & 2 deletions
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: 44e8467dc5e0e3cc91e46840d4a1ae686ee6c0a6 */
2+
* Stub hash: e85b15919120073579b1d561326eb1c3e446860a */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread_Map___construct, 0, 0, 0)
55
ZEND_END_ARG_INFO()
@@ -44,4 +44,4 @@ ZEND_END_ARG_INFO()
4444
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Map_clean, 0, 0, IS_VOID, 0)
4545
ZEND_END_ARG_INFO()
4646

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

ext-src/stubs/php_swoole_thread_queue.stub.php

Lines changed: 0 additions & 1 deletion
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
}

ext-src/stubs/php_swoole_thread_queue_arginfo.h

Lines changed: 1 addition & 3 deletions
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: c256829982b2a90c610e22862b13f0af86eaee6f */
2+
* Stub hash: 96a3f2b7103f36b83a3494d8b2f708a07a332b86 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread_Queue___construct, 0, 0, 0)
55
ZEND_END_ARG_INFO()
@@ -18,5 +18,3 @@ ZEND_END_ARG_INFO()
1818

1919
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Queue_clean, 0, 0, IS_VOID, 0)
2020
ZEND_END_ARG_INFO()
21-
22-
#define arginfo_class_Swoole_Thread_Queue___wakeup arginfo_class_Swoole_Thread_Queue_clean

ext-src/swoole_channel_coro.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static sw_inline ChannelObject *php_swoole_channel_coro_fetch_object(zend_object
6868
static sw_inline Channel *php_swoole_get_channel(zval *zobject) {
6969
Channel *chan = php_swoole_channel_coro_fetch_object(Z_OBJ_P(zobject))->chan;
7070
if (UNEXPECTED(!chan)) {
71-
php_swoole_fatal_error(E_ERROR, "you must call Channel constructor first");
71+
swoole_fatal_error(SW_ERROR_WRONG_OPERATION, "must call constructor first");
7272
}
7373
return chan;
7474
}

ext-src/swoole_http_client_coro.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1638,7 +1638,7 @@ static sw_inline HttpClientObject *http_client_coro_fetch_object(zend_object *ob
16381638
static sw_inline Client *http_client_coro_get_client(zval *zobject) {
16391639
Client *phc = http_client_coro_fetch_object(Z_OBJ_P(zobject))->client;
16401640
if (UNEXPECTED(!phc)) {
1641-
php_swoole_fatal_error(E_ERROR, "you must call Http Client constructor first");
1641+
swoole_fatal_error(SW_ERROR_WRONG_OPERATION, "must call constructor first");
16421642
}
16431643
return phc;
16441644
}

ext-src/swoole_lock.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ static Lock *php_swoole_lock_get_ptr(zval *zobject) {
4949

5050
static Lock *php_swoole_lock_get_and_check_ptr(zval *zobject) {
5151
Lock *lock = php_swoole_lock_get_ptr(zobject);
52-
if (!lock) {
53-
php_swoole_fatal_error(E_ERROR, "must call constructor first");
52+
if (UNEXPECTED(!lock)) {
53+
swoole_fatal_error(SW_ERROR_WRONG_OPERATION, "must call constructor first");
5454
}
5555
return lock;
5656
}

ext-src/swoole_name_resolver.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ static zend_always_inline ContextObject *swoole_name_resolver_context_get_object
4444

4545
static zend_always_inline ContextObject *swoole_name_resolver_context_get_object_safe(zend_object *object) {
4646
NameResolver::Context *name_resolver_context = swoole_name_resolver_context_get_handle(object);
47-
if (!name_resolver_context) {
48-
php_swoole_fatal_error(E_ERROR, "must call name_resolver_context constructor first");
47+
if (UNEXPECTED(!name_resolver_context)) {
48+
swoole_fatal_error(SW_ERROR_WRONG_OPERATION, "must call constructor first");
4949
}
5050
return swoole_name_resolver_context_get_object(object);
5151
}

ext-src/swoole_process.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ Worker *php_swoole_process_get_worker(zval *zobject) {
5151

5252
Worker *php_swoole_process_get_and_check_worker(zval *zobject) {
5353
Worker *worker = php_swoole_process_get_worker(zobject);
54-
if (!worker) {
55-
php_swoole_fatal_error(E_ERROR, "must call constructor first");
54+
if (UNEXPECTED(!worker)) {
55+
swoole_fatal_error(SW_ERROR_WRONG_OPERATION, "must call constructor first");
5656
}
5757
return worker;
5858
}

ext-src/swoole_process_pool.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ static sw_inline ProcessPool *process_pool_get_pool(zval *zobject) {
5858

5959
static sw_inline ProcessPool *process_pool_get_and_check_pool(zval *zobject) {
6060
ProcessPool *pool = process_pool_get_pool(zobject);
61-
if (!pool) {
62-
php_swoole_fatal_error(E_ERROR, "you must call Process\\Pool constructor first");
61+
if (UNEXPECTED(!pool)) {
62+
swoole_fatal_error(SW_ERROR_WRONG_OPERATION, "must call constructor first");
6363
}
6464
return pool;
6565
}

0 commit comments

Comments
 (0)