Skip to content

Commit 681f29e

Browse files
committed
Move caller back to zend_fiber
Caller is specific to treating fibers as a stack, so keep it with that implementation. If an implementation jumped between fibers, caller can be misleading or inaccurate.
1 parent 835279a commit 681f29e

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

Zend/zend_fibers.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -240,18 +240,11 @@ ZEND_API zend_fiber_context *zend_fiber_switch_context(zend_fiber_context *to)
240240
zend_fiber_capture_vm_state(&state);
241241

242242
to->status = ZEND_FIBER_STATUS_RUNNING;
243-
if (to->caller == NULL) {
244-
to->caller = from;
245-
}
246243

247244
if (from->status == ZEND_FIBER_STATUS_RUNNING) {
248245
from->status = ZEND_FIBER_STATUS_SUSPENDED;
249246
}
250247

251-
if (from->caller == to) {
252-
from->caller = NULL;
253-
}
254-
255248
EG(current_fiber) = to;
256249

257250
#ifdef __SANITIZE_ADDRESS__
@@ -353,7 +346,10 @@ static ZEND_STACK_ALIGNED zend_fiber_context *zend_fiber_execute(zend_fiber_cont
353346
fiber->execute_data = NULL;
354347
fiber->stack_bottom = NULL;
355348

356-
return fiber->caller;
349+
zend_fiber_context *caller = fiber->caller;
350+
fiber->caller = NULL;
351+
352+
return caller;
357353
}
358354

359355
static zend_object *zend_fiber_object_create(zend_class_entry *ce)
@@ -380,6 +376,7 @@ static void zend_fiber_object_destroy(zend_object *object)
380376
zend_object *exception = EG(exception);
381377
EG(exception) = NULL;
382378

379+
fiber->caller = EG(current_fiber);
383380
fiber->flags |= ZEND_FIBER_FLAG_DESTROYED;
384381

385382
zend_fiber_switch_context(zend_fiber_get_context(fiber));
@@ -452,6 +449,8 @@ ZEND_METHOD(Fiber, start)
452449
RETURN_THROWS();
453450
}
454451

452+
fiber->caller = EG(current_fiber);
453+
455454
zend_fiber_switch_context(context);
456455

457456
if (fiber->status == ZEND_FIBER_STATUS_DEAD) {
@@ -477,24 +476,27 @@ ZEND_METHOD(Fiber, suspend)
477476
}
478477

479478
zend_fiber *fiber = zend_fiber_from_context(EG(current_fiber));
479+
zend_fiber_context *caller = fiber->caller;
480480

481481
if (UNEXPECTED(fiber->flags & ZEND_FIBER_FLAG_DESTROYED)) {
482482
zend_throw_error(zend_ce_fiber_error, "Cannot suspend in a force-closed fiber");
483483
RETURN_THROWS();
484484
}
485485

486486
ZEND_ASSERT(fiber->status == ZEND_FIBER_STATUS_RUNNING);
487+
ZEND_ASSERT(caller != NULL);
487488

488489
if (value) {
489490
ZVAL_COPY(&fiber->value, value);
490491
} else {
491492
ZVAL_NULL(&fiber->value);
492493
}
493494

495+
fiber->caller = NULL;
494496
fiber->execute_data = EG(current_execute_data);
495497
fiber->stack_bottom->prev_execute_data = NULL;
496498

497-
zend_fiber_switch_context(fiber->caller);
499+
zend_fiber_switch_context(caller);
498500

499501
if (fiber->flags & ZEND_FIBER_FLAG_DESTROYED) {
500502
// This occurs when the fiber is GC'ed while suspended.
@@ -537,6 +539,7 @@ ZEND_METHOD(Fiber, resume)
537539
ZVAL_NULL(&fiber->value);
538540
}
539541

542+
fiber->caller = EG(current_fiber);
540543
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
541544

542545
zend_fiber_switch_context(zend_fiber_get_context(fiber));
@@ -568,6 +571,7 @@ ZEND_METHOD(Fiber, throw)
568571
Z_ADDREF_P(exception);
569572
fiber->exception = exception;
570573

574+
fiber->caller = EG(current_fiber);
571575
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
572576

573577
zend_fiber_switch_context(zend_fiber_get_context(fiber));
@@ -693,7 +697,6 @@ void zend_fiber_init(void)
693697
zend_fiber_context *context = ecalloc(1, sizeof(zend_fiber_context));
694698

695699
context->status = ZEND_FIBER_STATUS_RUNNING;
696-
context->caller = (zend_fiber_context *) -1;
697700

698701
EG(main_fiber) = context;
699702
EG(current_fiber) = context;

Zend/zend_fibers.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ typedef zend_fiber_context *(*zend_fiber_coroutine)(zend_fiber_context *context)
7676
void *handle; \
7777
/* Pointer that identifies the fiber type. */ \
7878
void *kind; \
79-
zend_fiber_context *caller; \
8079
zend_fiber_coroutine function; \
8180
zend_fiber_stack stack; \
8281
zend_fiber_status status; \
@@ -106,6 +105,9 @@ struct _zend_fiber {
106105
/* Fiber context fields (embedded to avoid memory allocation). */
107106
ZEND_FIBER_CONTEXT_FIELDS;
108107

108+
/* Fiber that resumed us. */
109+
zend_fiber_context *caller;
110+
109111
/* Callback and info / cache to be used when fiber is started. */
110112
zend_fcall_info fci;
111113
zend_fcall_info_cache fci_cache;

ext/zend_test/test.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,12 @@ static void fiber_enter_observer(zend_fiber_context *from, zend_fiber_context *t
436436
if (ZT_G(observer_fiber_switch)) {
437437
if (to->status == ZEND_FIBER_STATUS_INIT) {
438438
php_printf("<init '%p'>\n", to);
439-
} else if (to->caller == NULL) {
439+
} else if (to != EG(main_fiber)) {
440+
zend_fiber *fiber = zend_fiber_from_context(to);
441+
if (fiber->caller != from) {
442+
return;
443+
}
444+
440445
if (to->flags & ZEND_FIBER_FLAG_DESTROYED) {
441446
php_printf("<destroying '%p'>\n", to);
442447
} else if (to->status != ZEND_FIBER_STATUS_DEAD) {
@@ -449,16 +454,19 @@ static void fiber_enter_observer(zend_fiber_context *from, zend_fiber_context *t
449454
static void fiber_suspend_observer(zend_fiber_context *from, zend_fiber_context *to)
450455
{
451456
if (ZT_G(observer_fiber_switch)) {
452-
if (from->caller == to && from->status == ZEND_FIBER_STATUS_RUNNING) {
453-
php_printf("<suspend '%p'>\n", from);
454-
} else if (from->status == ZEND_FIBER_STATUS_DEAD) {
457+
if (from->status == ZEND_FIBER_STATUS_DEAD) {
455458
if (from->flags & ZEND_FIBER_FLAG_THREW) {
456459
php_printf("<threw '%p'>\n", from);
457460
} else if (from->flags & ZEND_FIBER_FLAG_DESTROYED) {
458461
php_printf("<destroyed '%p'>\n", from);
459462
} else {
460463
php_printf("<returned '%p'>\n", from);
461464
}
465+
} else if (from != EG(main_fiber)) {
466+
zend_fiber *fiber = zend_fiber_from_context(from);
467+
if (fiber->caller == NULL) {
468+
php_printf("<suspend '%p'>\n", from);
469+
}
462470
}
463471
}
464472
}

0 commit comments

Comments
 (0)