Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
matyhtf committed Apr 23, 2024
1 parent d0e8154 commit 2589cfc
Show file tree
Hide file tree
Showing 31 changed files with 1,850 additions and 1,218 deletions.
5 changes: 5 additions & 0 deletions ext-src/php_swoole.cc
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,11 @@ PHP_MINIT_FUNCTION(swoole) {
#endif
#ifdef SW_THREAD
php_swoole_thread_minit(module_number);
php_swoole_thread_atomic_minit(module_number);
php_swoole_thread_lock_minit(module_number);
php_swoole_thread_queue_minit(module_number);
php_swoole_thread_map_minit(module_number);
php_swoole_thread_arraylist_minit(module_number);
#endif

SwooleG.fatal_error = fatal_error;
Expand Down
5 changes: 5 additions & 0 deletions ext-src/php_swoole_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ void php_swoole_redis_server_minit(int module_number);
void php_swoole_name_resolver_minit(int module_number);
#ifdef SW_THREAD
void php_swoole_thread_minit(int module_number);
void php_swoole_thread_atomic_minit(int module_number);
void php_swoole_thread_lock_minit(int module_number);
void php_swoole_thread_queue_minit(int module_number);
void php_swoole_thread_map_minit(int module_number);
void php_swoole_thread_arraylist_minit(int module_number);
#endif

/**
Expand Down
271 changes: 271 additions & 0 deletions ext-src/php_swoole_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

#ifdef SW_THREAD

#include "swoole_lock.h"

typedef uint32_t ThreadResourceId;
struct ThreadResource;

Expand Down Expand Up @@ -55,4 +57,273 @@ struct ThreadResource {
}
};


struct ArrayItem {
uint32_t type;
zend_string *key;
union {
zend_string *str;
zend_long lval;
double dval;
zend_string *serialized_object;
} value;

ArrayItem(zval *zvalue) {
key = nullptr;
value = {};
store(zvalue);
}

void store(zval *zvalue) {
type = Z_TYPE_P(zvalue);
switch (type) {
case IS_LONG:
value.lval = zval_get_long(zvalue);
break;
case IS_DOUBLE:
value.dval = zval_get_double(zvalue);
break;
case IS_STRING: {
value.str = zend_string_init(Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue), 1);
break;
case IS_TRUE:
case IS_FALSE:
case IS_NULL:
break;
}
default: {
auto _serialized_object = php_swoole_thread_serialize(zvalue);
if (!_serialized_object) {
type = IS_UNDEF;
break;
} else {
type = IS_SERIALIZED_OBJECT;
value.serialized_object = _serialized_object;
}
break;
}
}
}

void fetch(zval *return_value) {
switch (type) {
case IS_LONG:
RETVAL_LONG(value.lval);
break;
case IS_DOUBLE:
RETVAL_LONG(value.dval);
break;
case IS_TRUE:
RETVAL_TRUE;
break;
case IS_FALSE:
RETVAL_FALSE;
break;
case IS_STRING:
RETVAL_NEW_STR(zend_string_init(ZSTR_VAL(value.str), ZSTR_LEN(value.str), 0));
break;
case IS_SERIALIZED_OBJECT:
php_swoole_thread_unserialize(value.serialized_object, return_value);
break;
default:
break;
}
}

void release() {
if (type == IS_STRING) {
zend_string_release(value.str);
value.str = nullptr;
} else if (type == IS_SERIALIZED_OBJECT) {
zend_string_release(value.serialized_object);
value.serialized_object = nullptr;
}
}

~ArrayItem() {
if (value.str) {
release();
}
if (key) {
zend_string_release(key);
}
}
};

struct ZendArray : ThreadResource {
swoole::RWLock lock_;
zend_array ht;

static void item_dtor(zval *pDest) {
ArrayItem *item = (ArrayItem *) Z_PTR_P(pDest);
delete item;
}

ZendArray() : ThreadResource(), lock_(0) {
zend_hash_init(&ht, 0, NULL, item_dtor, 1);
}

~ZendArray() {
zend_hash_destroy(&ht);
}

void clean() {
lock_.lock();
zend_hash_clean(&ht);
lock_.unlock();
}

bool index_exists(zend_long index) {
return index < (zend_long) zend_hash_num_elements(&ht);
}

void strkey_offsetGet(zval *zkey, zval *return_value) {
zend::String skey(zkey);
lock_.lock_rd();
ArrayItem *item = (ArrayItem *) zend_hash_find_ptr(&ht, skey.get());
if (item) {
item->fetch(return_value);
}
lock_.unlock();
}

void strkey_offsetExists(zval *zkey, zval *return_value) {
zend::String skey(zkey);
lock_.lock_rd();
RETVAL_BOOL(zend_hash_find_ptr(&ht, skey.get()) != NULL);
lock_.unlock();
}

void strkey_offsetUnset(zval *zkey) {
zend::String skey(zkey);
lock_.lock();
zend_hash_del(&ht, skey.get());
lock_.unlock();
}

void strkey_offsetSet(zval *zkey, zval *zvalue) {
zend::String skey(zkey);
auto item = new ArrayItem(zvalue);
item->key = zend_string_init(skey.val(), skey.len(), 1);
lock_.lock();
zend_hash_update_ptr(&ht, item->key, item);
lock_.unlock();
}

void count(zval *return_value) {
lock_.lock_rd();
RETVAL_LONG(zend_hash_num_elements(&ht));
lock_.unlock();
}

void keys(zval *return_value) {
lock_.lock_rd();
zend_ulong elem_count = zend_hash_num_elements(&ht);
array_init_size(return_value, elem_count);
zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
zend_ulong num_idx;
zend_string *str_idx;
zval *entry;
ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
if (HT_IS_PACKED(&ht) && HT_IS_WITHOUT_HOLES(&ht)) {
/* Optimistic case: range(0..n-1) for vector-like packed array */
zend_ulong lval = 0;

for (; lval < elem_count; ++lval) {
ZEND_HASH_FILL_SET_LONG(lval);
ZEND_HASH_FILL_NEXT();
}
} else {
/* Go through input array and add keys to the return array */
ZEND_HASH_FOREACH_KEY_VAL(&ht, num_idx, str_idx, entry) {
if (str_idx) {
ZEND_HASH_FILL_SET_STR(zend_string_init(str_idx->val, str_idx->len, 0));
} else {
ZEND_HASH_FILL_SET_LONG(num_idx);
}
ZEND_HASH_FILL_NEXT();
}
ZEND_HASH_FOREACH_END();
}
(void) entry;
}
ZEND_HASH_FILL_END();
lock_.unlock();
}

void intkey_offsetGet(zend_long index, zval *return_value) {
lock_.lock_rd();
ArrayItem *item = (ArrayItem *) zend_hash_index_find_ptr(&ht, index);
if (item) {
item->fetch(return_value);
}
lock_.unlock();
}

void intkey_offsetGet(zval *zkey, zval *return_value) {
intkey_offsetGet(zval_get_long(zkey), return_value);
}

void intkey_offsetExists(zval *zkey, zval *return_value) {
zend_long index = zval_get_long(zkey);
lock_.lock_rd();
RETVAL_BOOL(zend_hash_index_find_ptr(&ht, index) != NULL);
lock_.unlock();
}

void intkey_offsetUnset(zval *zkey) {
zend_long index = zval_get_long(zkey);
lock_.lock();
zend_hash_index_del(&ht, index);
lock_.unlock();
}

void intkey_offsetSet(zval *zkey, zval *zvalue) {
zend_long index = zval_get_long(zkey);
auto item = new ArrayItem(zvalue);
lock_.lock();
zend_hash_index_update_ptr(&ht, index, item);
lock_.unlock();
}

bool index_offsetGet(zval *zkey, zval *return_value) {
zend_long index = zval_get_long(zkey);
bool out_of_range = true;
lock_.lock_rd();
if (index_exists(index)) {
out_of_range = false;
ArrayItem *item = (ArrayItem *) zend_hash_index_find_ptr(&ht, index);
if (item) {
item->fetch(return_value);
}
}
lock_.unlock();
return !out_of_range;
}

bool index_offsetSet(zval *zkey, zval *zvalue) {
zend_long index = ZVAL_IS_NULL(zkey) ? -1 : zval_get_long(zkey);
auto item = new ArrayItem(zvalue);
bool success = true;
lock_.lock();
if (index > zend_hash_num_elements(&ht)) {
success = false;
delete item;
} else if (index == -1 || index == zend_hash_num_elements(&ht)) {
zend_hash_next_index_insert_ptr(&ht, item);
} else {
zend_hash_index_update_ptr(&ht, index, item);
}
lock_.unlock();
return success;
}

void index_offsetExists(zval *zkey, zval *return_value) {
zend_long index = zval_get_long(zkey);
lock_.lock_rd();
RETVAL_BOOL(index_exists(index));
lock_.unlock();
}
};

#endif
6 changes: 0 additions & 6 deletions ext-src/stubs/php_swoole_atomic.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ public function set(int $value): void {}
public function cmpset(int $cmp_value, int $new_value): bool {}
public function wait(float $timeout = 1.0): bool {}
public function wakeup(int $count = 1): bool {}
#ifdef SW_THREAD
public function __wakeup(): void {}
#endif
}
}

Expand All @@ -23,8 +20,5 @@ public function sub(int $sub_value = 1): int {}
public function get(): int {}
public function set(int $value): void {}
public function cmpset(int $cmp_value, int $new_value): bool {}
#ifdef SW_THREAD
public function __wakeup(): void {}
#endif
}
}
11 changes: 1 addition & 10 deletions ext-src/stubs/php_swoole_atomic_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 081724c8ea467fa6daf08906f0d0fcb7603795ed */
* Stub hash: 7c83f8fbe7fd48ac2c7a2756a4e33a9edd666e42 */

ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Atomic___construct, 0, 0, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_LONG, 0, "0")
Expand Down Expand Up @@ -33,11 +33,6 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Atomic_wakeup, 0, 0
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, count, IS_LONG, 0, "1")
ZEND_END_ARG_INFO()

#if defined(SW_THREAD)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Atomic___wakeup, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()
#endif

#define arginfo_class_Swoole_Atomic_Long___construct arginfo_class_Swoole_Atomic___construct

#define arginfo_class_Swoole_Atomic_Long_add arginfo_class_Swoole_Atomic_add
Expand All @@ -49,7 +44,3 @@ ZEND_END_ARG_INFO()
#define arginfo_class_Swoole_Atomic_Long_set arginfo_class_Swoole_Atomic_set

#define arginfo_class_Swoole_Atomic_Long_cmpset arginfo_class_Swoole_Atomic_cmpset

#if defined(SW_THREAD)
#define arginfo_class_Swoole_Atomic_Long___wakeup arginfo_class_Swoole_Atomic___wakeup
#endif
5 changes: 1 addition & 4 deletions ext-src/stubs/php_swoole_lock.stub.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
namespace Swoole {
class Lock {
public function __construct(int $type = SWOOLE_MUTEX, string $filename = '') {}
public function __construct(int $type = SWOOLE_MUTEX) {}
public function __destruct() {}
public function lock(): bool {}
public function locakwait(float $timeout = 1.0): bool {}
Expand All @@ -10,8 +10,5 @@ public function lock_read(): bool {}
public function trylock_read(): bool {}
public function unlock(): bool {}
public function destroy(): void {}
#ifdef SW_THREAD
public function __wakeup(): void {}
#endif
}
}
8 changes: 1 addition & 7 deletions ext-src/stubs/php_swoole_lock_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: ba4e97afe28b9cd1d6f0de33c10827fc3382c952 */
* Stub hash: e81e08c6ba7d087c2a3e55dade7b2dd3c788ae3f */

ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Lock___construct, 0, 0, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_LONG, 0, "SWOOLE_MUTEX")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filename, IS_STRING, 0, "\'\'")
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Lock___destruct, 0, 0, 0)
Expand All @@ -26,8 +25,3 @@ ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Lock_destroy, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()

#if defined(SW_THREAD)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Lock___wakeup, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()
#endif
Loading

0 comments on commit 2589cfc

Please sign in to comment.