Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Comprehensive test coverage for all fiber scenarios
- **TrueAsync API**: Added `ZEND_ASYNC_SCHEDULER_LAUNCH()` macro for scheduler initialization
- **TrueAsync API**: Updated to version 0.8.0 with fiber support
- **TrueAsync API**: Added customizable scheduler heartbeat handler mechanism with `zend_async_set_heartbeat_handler()` API

### Fixed
- **Critical GC Bug**: Fixed garbage collection crash during coroutine cancellation when exception occurs in main coroutine while GC is running
Expand Down
12 changes: 8 additions & 4 deletions scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,8 @@ static zend_always_inline void scheduler_next_tick(void)
zend_object **exception_ptr = &EG(exception);
zend_object **prev_exception_ptr = &EG(prev_exception);

ZEND_ASYNC_SCHEDULER_HEARTBEAT;

execute_microtasks();
TRY_HANDLE_SUSPEND_EXCEPTION();

Expand Down Expand Up @@ -1195,8 +1197,6 @@ bool async_scheduler_coroutine_suspend(void)
}
}

ZEND_ASYNC_SCHEDULER_HEARTBEAT;

zend_coroutine_t *coroutine = ZEND_ASYNC_CURRENT_COROUTINE;

//
Expand Down Expand Up @@ -1330,6 +1330,7 @@ ZEND_STACK_ALIGNED void fiber_entry(zend_fiber_transfer *transfer)
// Allocate VM stack on C stack instead of heap
char vm_stack_memory[ZEND_FIBER_VM_STACK_SIZE];
bool *in_scheduler_context = &ZEND_ASYNC_SCHEDULER_CONTEXT;
zend_async_heartbeat_handler_t *heartbeat_handler = &ZEND_ASYNC_G(heartbeat_handler);

zend_first_try
{
Expand Down Expand Up @@ -1380,10 +1381,13 @@ ZEND_STACK_ALIGNED void fiber_entry(zend_fiber_transfer *transfer)

TRY_HANDLE_EXCEPTION();

ZEND_ASYNC_SCHEDULER_HEARTBEAT;

*in_scheduler_context = true;

//ZEND_ASYNC_SCHEDULER_HEARTBEAT;
if (*heartbeat_handler) {
(*heartbeat_handler)();
}

ZEND_ASSERT(circular_buffer_is_not_empty(resumed_coroutines) == 0 && "resumed_coroutines should be 0");

execute_microtasks();
Expand Down
6 changes: 3 additions & 3 deletions tests/curl/005-error_handling.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ $coroutines = [
spawn(fn() => test_not_found($server)),
];

$results = await_all($coroutines);
[$results, $exceptions] = await_all($coroutines);

// Merge all outputs and sort by key to ensure deterministic order
$all_output = [];
Expand All @@ -102,14 +102,14 @@ async_test_server_stop($server);
--EXPECTF--
Test start
Testing connection error
Testing server error
Testing 404 error
Connection failed as expected
Error present: yes
Error number: %d
Testing server error
HTTP Code: 500
Error: none
Response length: %d
Testing 404 error
HTTP Code: 404
Response length: %d
Test end
Loading