Skip to content

Commit 6f95648

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 betweend fibers, caller can be misleading or inaccurate.
1 parent f3cbc8d commit 6f95648

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
@@ -237,18 +237,11 @@ ZEND_API zend_fiber_context *zend_fiber_switch_context(zend_fiber_context *to)
237237
zend_fiber_capture_vm_state(&state);
238238

239239
to->status = ZEND_FIBER_STATUS_RUNNING;
240-
if (to->caller == NULL) {
241-
to->caller = from;
242-
}
243240

244241
if (from->status == ZEND_FIBER_STATUS_RUNNING) {
245242
from->status = ZEND_FIBER_STATUS_SUSPENDED;
246243
}
247244

248-
if (from->caller == to) {
249-
from->caller = NULL;
250-
}
251-
252245
EG(current_fiber) = to;
253246

254247
#ifdef __SANITIZE_ADDRESS__
@@ -350,7 +343,10 @@ static ZEND_STACK_ALIGNED zend_fiber_context *zend_fiber_execute(zend_fiber_cont
350343
fiber->execute_data = NULL;
351344
fiber->stack_bottom = NULL;
352345

353-
return fiber->caller;
346+
zend_fiber_context *caller = fiber->caller;
347+
fiber->caller = NULL;
348+
349+
return caller;
354350
}
355351

356352
static zend_object *zend_fiber_object_create(zend_class_entry *ce)
@@ -377,6 +373,7 @@ static void zend_fiber_object_destroy(zend_object *object)
377373
zend_object *exception = EG(exception);
378374
EG(exception) = NULL;
379375

376+
fiber->caller = EG(current_fiber);
380377
fiber->flags |= ZEND_FIBER_FLAG_DESTROYED;
381378

382379
zend_fiber_switch_context(zend_fiber_get_context(fiber));
@@ -449,6 +446,8 @@ ZEND_METHOD(Fiber, start)
449446
RETURN_THROWS();
450447
}
451448

449+
fiber->caller = EG(current_fiber);
450+
452451
zend_fiber_switch_context(context);
453452

454453
if (fiber->status == ZEND_FIBER_STATUS_DEAD) {
@@ -474,24 +473,27 @@ ZEND_METHOD(Fiber, suspend)
474473
}
475474

476475
zend_fiber *fiber = zend_fiber_from_context(EG(current_fiber));
476+
zend_fiber_context *caller = fiber->caller;
477477

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

483483
ZEND_ASSERT(fiber->status == ZEND_FIBER_STATUS_RUNNING);
484+
ZEND_ASSERT(caller != NULL);
484485

485486
if (value) {
486487
ZVAL_COPY(&fiber->value, value);
487488
} else {
488489
ZVAL_NULL(&fiber->value);
489490
}
490491

492+
fiber->caller = NULL;
491493
fiber->execute_data = EG(current_execute_data);
492494
fiber->stack_bottom->prev_execute_data = NULL;
493495

494-
zend_fiber_switch_context(fiber->caller);
496+
zend_fiber_switch_context(caller);
495497

496498
if (fiber->flags & ZEND_FIBER_FLAG_DESTROYED) {
497499
// This occurs when the fiber is GC'ed while suspended.
@@ -534,6 +536,7 @@ ZEND_METHOD(Fiber, resume)
534536
ZVAL_NULL(&fiber->value);
535537
}
536538

539+
fiber->caller = EG(current_fiber);
537540
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
538541

539542
zend_fiber_switch_context(zend_fiber_get_context(fiber));
@@ -565,6 +568,7 @@ ZEND_METHOD(Fiber, throw)
565568
Z_ADDREF_P(exception);
566569
fiber->exception = exception;
567570

571+
fiber->caller = EG(current_fiber);
568572
fiber->stack_bottom->prev_execute_data = EG(current_execute_data);
569573

570574
zend_fiber_switch_context(zend_fiber_get_context(fiber));
@@ -690,7 +694,6 @@ void zend_fiber_init(void)
690694
zend_fiber_context *context = ecalloc(1, sizeof(zend_fiber_context));
691695

692696
context->status = ZEND_FIBER_STATUS_RUNNING;
693-
context->caller = (zend_fiber_context *) -1;
694697

695698
EG(main_fiber) = context;
696699
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 void *zend_fiber_asm_handle;
7676
/* Defined as a macro to allow anonymous embedding. */
7777
#define ZEND_FIBER_CONTEXT_FIELDS \
7878
zend_fiber_asm_handle handle; \
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
@@ -423,7 +423,12 @@ static void fiber_enter_observer(zend_fiber_context *from, zend_fiber_context *t
423423
if (ZT_G(observer_fiber_switch)) {
424424
if (to->status == ZEND_FIBER_STATUS_INIT) {
425425
php_printf("<init '%p'>\n", to);
426-
} else if (to->caller == NULL) {
426+
} else if (to != EG(main_fiber)) {
427+
zend_fiber *fiber = zend_fiber_from_context(to);
428+
if (fiber->caller != from) {
429+
return;
430+
}
431+
427432
if (to->flags & ZEND_FIBER_FLAG_DESTROYED) {
428433
php_printf("<destroying '%p'>\n", to);
429434
} else if (to->status != ZEND_FIBER_STATUS_DEAD) {
@@ -436,16 +441,19 @@ static void fiber_enter_observer(zend_fiber_context *from, zend_fiber_context *t
436441
static void fiber_suspend_observer(zend_fiber_context *from, zend_fiber_context *to)
437442
{
438443
if (ZT_G(observer_fiber_switch)) {
439-
if (from->caller == to && from->status == ZEND_FIBER_STATUS_RUNNING) {
440-
php_printf("<suspend '%p'>\n", from);
441-
} else if (from->status == ZEND_FIBER_STATUS_DEAD) {
444+
if (from->status == ZEND_FIBER_STATUS_DEAD) {
442445
if (from->flags & ZEND_FIBER_FLAG_THREW) {
443446
php_printf("<threw '%p'>\n", from);
444447
} else if (from->flags & ZEND_FIBER_FLAG_DESTROYED) {
445448
php_printf("<destroyed '%p'>\n", from);
446449
} else {
447450
php_printf("<returned '%p'>\n", from);
448451
}
452+
} else if (from != EG(main_fiber)) {
453+
zend_fiber *fiber = zend_fiber_from_context(from);
454+
if (fiber->caller == NULL) {
455+
php_printf("<suspend '%p'>\n", from);
456+
}
449457
}
450458
}
451459
}

0 commit comments

Comments
 (0)