Skip to content

Commit

Permalink
[test] fix tests [4]
Browse files Browse the repository at this point in the history
  • Loading branch information
matyhtf committed Apr 17, 2024
1 parent d66eabf commit 93d6cec
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 24 deletions.
76 changes: 54 additions & 22 deletions ext-src/swoole_runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,7 @@ static bool runtime_hook_init = false;
static int runtime_hook_flags = 0;
static SW_THREAD_LOCAL zend_array *tmp_function_table = nullptr;
static SW_THREAD_LOCAL std::unordered_map<std::string, zend_class_entry *> child_class_entries;

#ifdef SW_THREAD
static std::unordered_map<std::string, zif_handler> ori_func_handlers;
#endif

SW_EXTERN_C_BEGIN
#include "ext/standard/file.h"
Expand Down Expand Up @@ -265,7 +262,10 @@ void php_swoole_runtime_mshutdown() {
#ifdef SW_USE_CURL
swoole_native_curl_mshutdown();
#endif
#ifdef SW_THREAD
PHPCoroutine::disable_hook();
#endif
ori_func_handlers.clear();
}

static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *portno, int get_err, zend_string **err) {
Expand Down Expand Up @@ -1173,6 +1173,12 @@ void PHPCoroutine::enable_unsafe_function() {
}

bool PHPCoroutine::enable_hook(uint32_t flags) {
#ifdef SW_THREAD
if (!tsrm_is_main_thread()) {
swoole_set_last_error(SW_ERROR_OPERATION_NOT_SUPPORT);
return false;
}
#endif
if (swoole_isset_hook((enum swGlobalHookType) PHP_SWOOLE_HOOK_BEFORE_ENABLE_HOOK)) {
swoole_call_hook((enum swGlobalHookType) PHP_SWOOLE_HOOK_BEFORE_ENABLE_HOOK, &flags);
}
Expand Down Expand Up @@ -1592,6 +1598,13 @@ static PHP_METHOD(swoole_runtime, enableCoroutine) {
}
}

#ifdef SW_THREAD
if (runtime_hook_init && flags == 0) {
swoole_set_last_error(SW_ERROR_OPERATION_NOT_SUPPORT);
RETURN_FALSE;
}
#endif

PHPCoroutine::set_hook_flags(flags);
RETURN_BOOL(PHPCoroutine::enable_hook(flags));
}
Expand All @@ -1615,6 +1628,15 @@ static PHP_METHOD(swoole_runtime, setHookFlags) {
Z_PARAM_LONG(flags)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

#ifdef SW_THREAD
// In a multi-threaded environment, disabling the hook is prohibited.
// It can only be enabled once in the main thread.
if (runtime_hook_init && flags == 0) {
swoole_set_last_error(SW_ERROR_OPERATION_NOT_SUPPORT);
RETURN_FALSE;
}
#endif

PHPCoroutine::set_hook_flags(flags);
RETURN_BOOL(PHPCoroutine::enable_hook(flags));
}
Expand Down Expand Up @@ -1950,6 +1972,7 @@ static void hook_func(const char *name, size_t l_name, zif_handler handler, zend
return;
}

auto fn_str = zf->common.function_name;
rf = (real_func *) emalloc(sizeof(real_func));
sw_memset_zero(rf, sizeof(*rf));
rf->function = zf;
Expand All @@ -1960,16 +1983,14 @@ static void hook_func(const char *name, size_t l_name, zif_handler handler, zend
zf->internal_function.arg_info = arg_info;
}

#ifdef SW_THREAD
ori_func_handlers[std::string(zf->common.function_name->val, zf->common.function_name->len)] = rf->ori_handler;
#endif
ori_func_handlers[std::string(fn_str->val, fn_str->len)] = rf->ori_handler;

if (use_php_func) {
char func[128];
memcpy(func, ZEND_STRL("swoole_"));
memcpy(func + 7, zf->common.function_name->val, zf->common.function_name->len);
memcpy(func + 7, fn_str->val, fn_str->len);

ZVAL_STRINGL(&rf->name, func, zf->common.function_name->len + 7);
ZVAL_STRINGL(&rf->name, func, fn_str->len + 7);

char *func_name;
zend_fcall_info_cache *func_cache = (zend_fcall_info_cache *) emalloc(sizeof(zend_fcall_info_cache));
Expand All @@ -1981,7 +2002,7 @@ static void hook_func(const char *name, size_t l_name, zif_handler handler, zend
rf->fci_cache = func_cache;
}

zend_hash_add_ptr(tmp_function_table, zf->common.function_name, rf);
zend_hash_add_ptr(tmp_function_table, fn_str, rf);
}

static void unhook_func(const char *name, size_t l_name) {
Expand Down Expand Up @@ -2059,22 +2080,33 @@ static PHP_FUNCTION(swoole_stream_socket_pair) {
}

static PHP_FUNCTION(swoole_user_func_handler) {
real_func *rf = (real_func *) zend_hash_find_ptr(tmp_function_table, execute_data->func->common.function_name);
if (rf) {
zend_fcall_info fci;
fci.size = sizeof(fci);
fci.object = nullptr;
fci.retval = return_value;
fci.param_count = ZEND_NUM_ARGS();
fci.params = ZEND_CALL_ARG(execute_data, 1);
fci.named_params = NULL;
ZVAL_UNDEF(&fci.function_name);
zend_call_function(&fci, rf->fci_cache);
} else {
zend_string *fn_str = execute_data->func->common.function_name;
auto fn_str = execute_data->func->common.function_name;
if (!swoole_coroutine_is_in()) {
auto ori_handler = ori_func_handlers[std::string(fn_str->val, fn_str->len)];
ori_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);
return;
}

real_func *rf = (real_func *) zend_hash_find_ptr(tmp_function_table, fn_str);
if (!rf) {
#ifdef SW_THREAD
hook_func(fn_str->val, fn_str->len);
rf = (real_func *) zend_hash_find_ptr(tmp_function_table, fn_str);
#else
zend_throw_exception_ex(swoole_exception_ce, SW_ERROR_UNDEFINED_BEHAVIOR, "%s func not exists", fn_str->val);
return;
#endif
}

zend_fcall_info fci;
fci.size = sizeof(fci);
fci.object = nullptr;
fci.retval = return_value;
fci.param_count = ZEND_NUM_ARGS();
fci.params = ZEND_CALL_ARG(execute_data, 1);
fci.named_params = NULL;
ZVAL_UNDEF(&fci.function_name);
zend_call_function(&fci, rf->fci_cache);
}

zend_class_entry *find_class_entry(const char *name, size_t length) {
Expand Down
1 change: 1 addition & 0 deletions include/swoole_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum swErrorCode {
SW_ERROR_PROTOCOL_ERROR,
SW_ERROR_WRONG_OPERATION,
SW_ERROR_PHP_RUNTIME_NOTICE, // Non-fatal errors, just runtime warnings
SW_ERROR_UNDEFINED_BEHAVIOR = 600,

SW_ERROR_FILE_NOT_EXIST = 700,
SW_ERROR_FILE_TOO_LARGE,
Expand Down
8 changes: 6 additions & 2 deletions tests/swoole_thread/pipe.phpt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
--TEST--
swoole_thread: lock
swoole_thread: pipe
--SKIPIF--
<?php
require __DIR__ . '/../include/skipif.inc';
Expand All @@ -23,10 +23,14 @@ if (empty($args)) {
echo "DONE\n";
});
} else {
$argv = $args[0];
$sockets = $args[1];
$rdata = $args[2];
Co\run(function () use ($sockets, $rdata){
// Child threads are not allowed to modify hook flags
Assert::false(Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL));
Co\run(function () use ($sockets, $rdata, $argv) {
usleep(100);
shell_exec('sleep 0.01');
$sockets[1]->send($rdata);
});
exit(0);
Expand Down

0 comments on commit 93d6cec

Please sign in to comment.