Skip to content

Commit

Permalink
Fix compatibility with PHP 8.3 (#5133)
Browse files Browse the repository at this point in the history
* Fix compatibility with PHP 8.3

* Support ZEND_CHECK_STACK_LIMIT

* Fix SW_USE_THREAD_CONTEXT

* Fix SW_USE_THREAD_CONTEXT

* Fix typo
  • Loading branch information
Yurunsoft authored Sep 29, 2023
1 parent c29da54 commit a11fd13
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
8 changes: 8 additions & 0 deletions ext-src/php_swoole_coroutine.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ struct PHPContext {
#ifdef SWOOLE_COROUTINE_MOCK_FIBER_CONTEXT
zend_fiber_context *fiber_context;
bool fiber_init_notified;
#endif
#ifdef ZEND_CHECK_STACK_LIMIT
void *stack_base;
void *stack_limit;
#endif
std::stack<zend::Function *> *defer_tasks;
SwapCallback *on_yield;
Expand Down Expand Up @@ -288,6 +292,10 @@ class PHPCoroutine {
static void fiber_context_try_destroy(PHPContext *ctx);
static void fiber_context_switch_notify(PHPContext *from, PHPContext *to);
static void fiber_context_switch_try_notify(PHPContext *from, PHPContext *to);
#endif
#ifdef ZEND_CHECK_STACK_LIMIT
static void* stack_limit(PHPContext *ctx);
static void* stack_base(PHPContext *ctx);
#endif
static void interrupt_thread_start();
static void record_last_msec(PHPContext *ctx) {
Expand Down
52 changes: 52 additions & 0 deletions ext-src/swoole_coroutine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ PHPContext *PHPCoroutine::create_context(Args *args) {
call->func = func;
EG(vm_stack_top) += ZEND_CALL_FRAME_SLOT;

#ifdef ZEND_CHECK_STACK_LIMIT
EG(stack_base) = stack_base(ctx);
EG(stack_limit) = stack_limit(ctx);
#endif

save_vm_stack(ctx);
record_last_msec(ctx);

Expand Down Expand Up @@ -483,6 +488,10 @@ inline void PHPCoroutine::save_vm_stack(PHPContext *ctx) {
ctx->tmp_error_reporting = EG(error_reporting);
EG(error_reporting) = ctx->ori_error_reporting;
}
#ifdef ZEND_CHECK_STACK_LIMIT
ctx->stack_base = EG(stack_base);
ctx->stack_limit = EG(stack_limit);
#endif
}

inline void PHPCoroutine::restore_vm_stack(PHPContext *ctx) {
Expand All @@ -505,6 +514,10 @@ inline void PHPCoroutine::restore_vm_stack(PHPContext *ctx) {
if (UNEXPECTED(ctx->in_silence)) {
EG(error_reporting) = ctx->tmp_error_reporting;
}
#ifdef ZEND_CHECK_STACK_LIMIT
EG(stack_base) = ctx->stack_base;
EG(stack_limit) = ctx->stack_limit;
#endif
}

inline void PHPCoroutine::save_og(PHPContext *ctx) {
Expand Down Expand Up @@ -844,6 +857,45 @@ void PHPCoroutine::fiber_context_switch_try_notify(PHPContext *from, PHPContext
}
#endif /* SWOOLE_COROUTINE_MOCK_FIBER_CONTEXT */

#ifdef ZEND_CHECK_STACK_LIMIT
void* PHPCoroutine::stack_limit(PHPContext *ctx)
{
#ifdef SW_USE_THREAD_CONTEXT
return nullptr;
#else
zend_ulong reserve = EG(reserved_stack_size);

#ifdef __APPLE__
/* On Apple Clang, the stack probing function ___chkstk_darwin incorrectly
* probes a location that is twice the entered function's stack usage away
* from the stack pointer, when using an alternative stack.
* https://openradar.appspot.com/radar?id=5497722702397440
*/
reserve = reserve * 2;
#endif

if (!ctx->co) {
return nullptr;
}

/* stack->pointer is the end of the stack */
return (int8_t*)ctx->co->get_ctx().get_stack() + reserve;
#endif
}
void* PHPCoroutine::stack_base(PHPContext *ctx)
{
#ifdef SW_USE_THREAD_CONTEXT
return nullptr;
#else
if (!ctx->co) {
return nullptr;
}

return (void*)((uintptr_t)ctx->co->get_ctx().get_stack() + ctx->co->get_ctx().get_stack_size());
#endif
}
#endif /* ZEND_CHECK_STACK_LIMIT */

void php_swoole_coroutine_minit(int module_number) {
SW_INIT_CLASS_ENTRY_BASE(swoole_coroutine_util, "Swoole\\Coroutine", "Co", swoole_coroutine_methods, nullptr);
SW_SET_CLASS_CREATE(swoole_coroutine_util, sw_zend_create_object_deny);
Expand Down
4 changes: 4 additions & 0 deletions include/swoole_coroutine.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ class Coroutine {
return time<seconds_type>(true) - switch_usec + execute_usec;
}

coroutine::Context &get_ctx() {
return ctx;
}

static std::unordered_map<long, Coroutine *> coroutines;

static void set_on_yield(SwapCallback func);
Expand Down
9 changes: 9 additions & 0 deletions include/swoole_coroutine_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ class Context {
bool swap_out();
#if !defined(SW_USE_THREAD_CONTEXT) && defined(SW_CONTEXT_DETECT_STACK_USAGE)
ssize_t get_stack_usage();
#endif
#ifndef SW_USE_THREAD_CONTEXT
char *get_stack() const {
return stack_;
}

size_t get_stack_size() const {
return stack_size_;
}
#endif
bool is_end() const {
return end_;
Expand Down

0 comments on commit a11fd13

Please sign in to comment.