Skip to content

Commit

Permalink
refactor runtime hook with ZTS
Browse files Browse the repository at this point in the history
  • Loading branch information
matyhtf committed Dec 13, 2024
1 parent 67ad28a commit 0b2e65a
Show file tree
Hide file tree
Showing 12 changed files with 215 additions and 140 deletions.
8 changes: 8 additions & 0 deletions ext-src/php_swoole.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1551,6 +1551,14 @@ static PHP_FUNCTION(swoole_implicit_fn) {
abort();
} else if (SW_STRCASEEQ(fn, l_fn, "refcount")) {
RETURN_LONG(zval_refcount_p(zargs));
} else if (SW_STRCASEEQ(fn, l_fn, "func_handler")) {
auto fn = zval_get_string(zargs);
zend_function *zf = (zend_function *) zend_hash_find(EG(function_table), fn);
zend_string_release(fn);
if (zf == nullptr) {
RETURN_FALSE;
}
printf("zif_handler=%p\n", zf->internal_function.handler);
} else {
zend_throw_exception_ex(swoole_exception_ce, SW_ERROR_INVALID_PARAMS, "unknown fn '%s'", fn);
}
Expand Down
51 changes: 36 additions & 15 deletions ext-src/php_swoole_cxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -638,40 +638,61 @@ class Callable {
}
};

template<typename KeyT, typename ValueT>
#define _CONCURRENCY_HASHMAP_LOCK_(code) \
if (locked_) { \
code; \
} else { \
lock_.lock(); \
code; \
lock_.unlock(); \
}

template <typename KeyT, typename ValueT>
class ConcurrencyHashMap {
private:
private:
std::unordered_map<KeyT, ValueT> map_;
std::mutex lock_;
bool locked_;
ValueT default_value_;

public:
ConcurrencyHashMap(ValueT _default_value): map_(), lock_() {
public:
ConcurrencyHashMap(ValueT _default_value) : map_(), lock_() {
default_value_ = _default_value;
locked_ = false;
}

void set(const KeyT &key, const ValueT &value) {
std::unique_lock<std::mutex> _lock(lock_);
map_[key] = value;
_CONCURRENCY_HASHMAP_LOCK_(map_[key] = value);
}

ValueT get(const KeyT &key) {
std::unique_lock<std::mutex> _lock(lock_);
auto iter = map_.find(key);
if (iter == map_.end()) {
return default_value_;
}
return iter->second;
ValueT value;
auto fn = [&]() -> ValueT {
auto iter = map_.find(key);
if (iter == map_.end()) {
return default_value_;
}
return iter->second;
};
_CONCURRENCY_HASHMAP_LOCK_(value = fn());
return value;
}

void del(const KeyT &key) {
std::unique_lock<std::mutex> _lock(lock_);
map_.erase(key);
_CONCURRENCY_HASHMAP_LOCK_(map_.erase(key));
}

void clear() {
_CONCURRENCY_HASHMAP_LOCK_(map_.clear());
}

void each(const std::function<void(KeyT key, ValueT value)> &cb) {
std::unique_lock<std::mutex> _lock(lock_);
map_.clear();
locked_ = true;
for (auto &iter : map_) {
cb(iter.first, iter.second);
}
locked_ = false;
}
};

Expand Down
2 changes: 1 addition & 1 deletion ext-src/stubs/php_swoole_runtime.stub.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
namespace Swoole {
class Runtime {
public static function enableCoroutine(bool|int $enable = SWOOLE_HOOK_ALL, int $flags = SWOOLE_HOOK_ALL): bool {}
public static function enableCoroutine(int $flags = SWOOLE_HOOK_ALL): bool {}
public static function getHookFlags(): int {}
public static function setHookFlags(int $flags): bool {}
}
Expand Down
3 changes: 1 addition & 2 deletions ext-src/stubs/php_swoole_runtime_arginfo.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 608f0058d657d34cb5e9b5b9f3a31feaa105b294 */
* Stub hash: c42e4c108dd49f37a5953391a69cdad50106f17d */

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Runtime_enableCoroutine, 0, 0, _IS_BOOL, 0)
ZEND_ARG_TYPE_MASK(0, enable, MAY_BE_BOOL|MAY_BE_LONG, "SWOOLE_HOOK_ALL")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "SWOOLE_HOOK_ALL")
ZEND_END_ARG_INFO()

Expand Down
23 changes: 10 additions & 13 deletions ext-src/swoole_coroutine_system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,6 @@ PHP_METHOD(swoole_coroutine_system, exec) {
Z_PARAM_BOOL(get_error_stream)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

if (php_swoole_signal_isset_handler(SIGCHLD)) {
php_swoole_error(E_WARNING, "The signal [SIGCHLD] is registered, cannot execute swoole_coroutine_exec");
RETURN_FALSE;
}

Coroutine::get_current_safe();

pid_t pid;
Expand All @@ -250,7 +245,7 @@ PHP_METHOD(swoole_coroutine_system, exec) {
RETURN_FALSE;
}

String *buffer = new String(1024);
auto buffer = std::shared_ptr<String>(swoole::make_string(1024, sw_zend_string_allocator()));
Socket socket(fd, SW_SOCK_UNIX_STREAM);
while (1) {
ssize_t retval = socket.read(buffer->str + buffer->length, buffer->size - buffer->length);
Expand All @@ -267,16 +262,16 @@ PHP_METHOD(swoole_coroutine_system, exec) {
}
socket.close();

auto str = zend::fetch_zend_string_by_val(buffer->str);
buffer->set_null_terminated();
str->len = buffer->length;
buffer->release();

zval zdata;
if (buffer->length == 0) {
ZVAL_EMPTY_STRING(&zdata);
} else {
ZVAL_STRINGL(&zdata, buffer->str, buffer->length);
}
delete buffer;
ZVAL_STR(&zdata, str);

int status;
pid_t _pid = swoole_coroutine_waitpid(pid, &status, 0);
pid_t _pid = System::waitpid_safe(pid, &status, 0);
if (_pid > 0) {
array_init(return_value);
add_assoc_long(return_value, "code", WEXITSTATUS(status));
Expand Down Expand Up @@ -310,6 +305,7 @@ static void swoole_coroutine_system_wait(INTERNAL_FUNCTION_PARAMETERS, pid_t pid
}

PHP_METHOD(swoole_coroutine_system, wait) {
SW_MUST_BE_MAIN_THREAD();
double timeout = -1;

ZEND_PARSE_PARAMETERS_START(0, 1)
Expand All @@ -321,6 +317,7 @@ PHP_METHOD(swoole_coroutine_system, wait) {
}

PHP_METHOD(swoole_coroutine_system, waitPid) {
SW_MUST_BE_MAIN_THREAD();
zend_long pid;
double timeout = -1;

Expand Down
Loading

0 comments on commit 0b2e65a

Please sign in to comment.