Skip to content

#41: add zend_observer_fiber_switch_notify when main coroutine create… #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 18, 2025
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
16 changes: 16 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
BasedOnStyle: WebKit
SortIncludes: 'false'
ColumnLimit: 100
IndentWidth: 4
TabWidth: 4
ContinuationIndentWidth: 8
UseTab: ForContinuationAndIndentation
PointerAlignment: Right
IndentCaseLabels: true
AlignConsecutiveAssignments: false
AlignEscapedNewlines: DontAlign
AllowShortFunctionsOnASingleLine: false
SpaceAfterCStyleCast: true
AlignOperands: false
...
16 changes: 16 additions & 0 deletions scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#include "exceptions.h"
#include "scope.h"
#include "zend_common.h"
#include "zend_observer.h"

static zend_function main_coroutine_root_function = { ZEND_INTERNAL_FUNCTION };

void async_scheduler_startup(void)
{
Expand Down Expand Up @@ -610,6 +613,19 @@ void async_scheduler_launch(void)
main_transfer->flags = 0;
ZVAL_NULL(&main_transfer->value);

//
// Because the main coroutine is created on the fly, this code is here.
// At the moment when PHP decides to activate the scheduler,
// we must normalize the observer's state and notify it that we are creating the main coroutine.
//
// This code contains a logical conflict because main_transfer is, in a way, the context of the zero coroutine.
// It's essentially a switch from the zero context to the coroutine context, even though,
// logically, both contexts belong to the main execution thread.
//
main_coroutine->context.status = ZEND_FIBER_STATUS_INIT;
zend_observer_fiber_switch_notify(main_transfer->context, &main_coroutine->context);
main_coroutine->context.status = ZEND_FIBER_STATUS_RUNNING;

ASYNC_G(main_transfer) = main_transfer;
ASYNC_G(main_vm_stack) = EG(vm_stack);

Expand Down
Loading