Skip to content

Commit f71d62e

Browse files
committed
Fiber cleanup
Add zend_fiber prefix to delegate_transfer_result(). Ensure status is set to INIT when initializing the fiber context in case memory is not zeroed. Assert destination fiber context is not dead. Update stack alloc failure messages. getThis() -> ZEND_THIS
1 parent c66fd72 commit f71d62e

File tree

1 file changed

+26
-23
lines changed

1 file changed

+26
-23
lines changed

Zend/zend_fibers.c

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static zend_fiber_stack *zend_fiber_stack_allocate(size_t size)
174174
if (!pointer) {
175175
DWORD err = GetLastError();
176176
char *errmsg = php_win32_error_to_msg(err);
177-
zend_throw_exception_ex(NULL, 0, "Fiber make context failed: VirtualAlloc failed: [0x%08lx] %s", err, errmsg[0] ? errmsg : "Unknown");
177+
zend_throw_exception_ex(NULL, 0, "Fiber stack allocate failed: VirtualAlloc failed: [0x%08lx] %s", err, errmsg[0] ? errmsg : "Unknown");
178178
php_win32_error_msg_free(errmsg);
179179
return NULL;
180180
}
@@ -185,7 +185,7 @@ static zend_fiber_stack *zend_fiber_stack_allocate(size_t size)
185185
if (!VirtualProtect(pointer, ZEND_FIBER_GUARD_PAGES * page_size, PAGE_READWRITE | PAGE_GUARD, &protect)) {
186186
DWORD err = GetLastError();
187187
char *errmsg = php_win32_error_to_msg(err);
188-
zend_throw_exception_ex(NULL, 0, "Fiber protect stack failed: VirtualProtect failed: [0x%08lx] %s", err, errmsg[0] ? errmsg : "Unknown");
188+
zend_throw_exception_ex(NULL, 0, "Fiber stack protect failed: VirtualProtect failed: [0x%08lx] %s", err, errmsg[0] ? errmsg : "Unknown");
189189
php_win32_error_msg_free(errmsg);
190190
VirtualFree(pointer, 0, MEM_RELEASE);
191191
return NULL;
@@ -195,13 +195,13 @@ static zend_fiber_stack *zend_fiber_stack_allocate(size_t size)
195195
pointer = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
196196

197197
if (pointer == MAP_FAILED) {
198-
zend_throw_exception_ex(NULL, 0, "Fiber make context failed: mmap failed: %s (%d)", strerror(errno), errno);
198+
zend_throw_exception_ex(NULL, 0, "Fiber stack allocate failed: mmap failed: %s (%d)", strerror(errno), errno);
199199
return NULL;
200200
}
201201

202202
# if ZEND_FIBER_GUARD_PAGES
203203
if (mprotect(pointer, ZEND_FIBER_GUARD_PAGES * page_size, PROT_NONE) < 0) {
204-
zend_throw_exception_ex(NULL, 0, "Fiber protect stack failed: mmap failed: %s (%d)", strerror(errno), errno);
204+
zend_throw_exception_ex(NULL, 0, "Fiber stack protect failed: mprotect failed: %s (%d)", strerror(errno), errno);
205205
munmap(pointer, alloc_size);
206206
return NULL;
207207
}
@@ -253,7 +253,7 @@ static ZEND_NORETURN void zend_fiber_trampoline(boost_context_data data)
253253
__sanitizer_finish_switch_fiber(NULL, &from->stack->asan_pointer, &from->stack->asan_size);
254254
#endif
255255

256-
/* Get a hold of the context that resumed us and update it's handle to allow for symmetric coroutines. */
256+
/* Get a hold of the context that resumed us and update its handle to allow for symmetric coroutines. */
257257
from->handle = data.handle;
258258

259259
/* Initialize transfer struct with a copy of passed data. */
@@ -309,6 +309,9 @@ ZEND_API bool zend_fiber_init_context(zend_fiber_context *context, void *kind, z
309309
context->kind = kind;
310310
context->function = coroutine;
311311

312+
// Set status in case memory has not been zeroed.
313+
context->status = ZEND_FIBER_STATUS_INIT;
314+
312315
return true;
313316
}
314317

@@ -323,7 +326,7 @@ ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer)
323326
zend_fiber_context *to = transfer->context;
324327
zend_fiber_vm_state state;
325328

326-
ZEND_ASSERT(to && to->handle && "Invalid fiber context");
329+
ZEND_ASSERT(to && to->handle && to->status != ZEND_FIBER_STATUS_DEAD && "Invalid fiber context");
327330
ZEND_ASSERT(from && "From fiber context must be present");
328331
ZEND_ASSERT(to != from && "Cannot switch into the running fiber context");
329332

@@ -365,7 +368,7 @@ ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer)
365368
/* Copy transfer struct because it might live on the other fiber's stack that will eventually be destroyed. */
366369
*transfer = *data.transfer;
367370

368-
/* Get a hold of the context that resumed us and update it's handle to allow for symmetric coroutines. */
371+
/* Get a hold of the context that resumed us and update its handle to allow for symmetric coroutines. */
369372
to = transfer->context;
370373
to->handle = data.handle;
371374

@@ -377,7 +380,7 @@ ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer)
377380

378381
zend_fiber_restore_vm_state(&state);
379382

380-
/* Destroy context first to ensure it does not leak if some extension does custom bailout handling. */
383+
/* Destroy prior context if it has been marked as dead. */
381384
if (to->status == ZEND_FIBER_STATUS_DEAD) {
382385
zend_fiber_destroy_context(to);
383386
}
@@ -450,7 +453,7 @@ static ZEND_STACK_ALIGNED void zend_fiber_execute(zend_fiber_transfer *transfer)
450453
}
451454

452455
/* Handles forwarding of result / error from a transfer into the running fiber. */
453-
static zend_always_inline void delegate_transfer_result(
456+
static zend_always_inline void zend_fiber_delegate_transfer_result(
454457
zend_fiber *fiber, zend_fiber_transfer *transfer, INTERNAL_FUNCTION_PARAMETERS
455458
) {
456459
if (transfer->flags & ZEND_FIBER_TRANSFER_FLAG_ERROR) {
@@ -579,7 +582,7 @@ static void zend_fiber_object_free(zend_object *object)
579582

580583
ZEND_METHOD(Fiber, __construct)
581584
{
582-
zend_fiber *fiber = (zend_fiber *) Z_OBJ_P(getThis());
585+
zend_fiber *fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
583586

584587
ZEND_PARSE_PARAMETERS_START(1, 1)
585588
Z_PARAM_FUNC(fiber->fci, fiber->fci_cache)
@@ -591,7 +594,7 @@ ZEND_METHOD(Fiber, __construct)
591594

592595
ZEND_METHOD(Fiber, start)
593596
{
594-
zend_fiber *fiber = (zend_fiber *) Z_OBJ_P(getThis());
597+
zend_fiber *fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
595598
zval *params;
596599
uint32_t param_count;
597600
zend_array *named_params;
@@ -622,7 +625,7 @@ ZEND_METHOD(Fiber, start)
622625

623626
zend_fiber_transfer transfer = zend_fiber_resume(fiber, NULL, false);
624627

625-
delegate_transfer_result(fiber, &transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
628+
zend_fiber_delegate_transfer_result(fiber, &transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
626629
}
627630

628631
ZEND_METHOD(Fiber, suspend)
@@ -665,7 +668,7 @@ ZEND_METHOD(Fiber, suspend)
665668
RETURN_THROWS();
666669
}
667670

668-
delegate_transfer_result(fiber, &transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
671+
zend_fiber_delegate_transfer_result(fiber, &transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
669672
}
670673

671674
ZEND_METHOD(Fiber, resume)
@@ -683,7 +686,7 @@ ZEND_METHOD(Fiber, resume)
683686
RETURN_THROWS();
684687
}
685688

686-
fiber = (zend_fiber *) Z_OBJ_P(getThis());
689+
fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
687690

688691
if (UNEXPECTED(fiber->context.status != ZEND_FIBER_STATUS_SUSPENDED || fiber->caller != NULL)) {
689692
zend_throw_error(zend_ce_fiber_error, "Cannot resume a fiber that is not suspended");
@@ -694,7 +697,7 @@ ZEND_METHOD(Fiber, resume)
694697

695698
zend_fiber_transfer transfer = zend_fiber_resume(fiber, value, false);
696699

697-
delegate_transfer_result(fiber, &transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
700+
zend_fiber_delegate_transfer_result(fiber, &transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
698701
}
699702

700703
ZEND_METHOD(Fiber, throw)
@@ -711,7 +714,7 @@ ZEND_METHOD(Fiber, throw)
711714
RETURN_THROWS();
712715
}
713716

714-
fiber = (zend_fiber *) Z_OBJ_P(getThis());
717+
fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
715718

716719
if (UNEXPECTED(fiber->context.status != ZEND_FIBER_STATUS_SUSPENDED || fiber->caller != NULL)) {
717720
zend_throw_error(zend_ce_fiber_error, "Cannot resume a fiber that is not suspended");
@@ -722,7 +725,7 @@ ZEND_METHOD(Fiber, throw)
722725

723726
zend_fiber_transfer transfer = zend_fiber_resume(fiber, exception, true);
724727

725-
delegate_transfer_result(fiber, &transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
728+
zend_fiber_delegate_transfer_result(fiber, &transfer, INTERNAL_FUNCTION_PARAM_PASSTHRU);
726729
}
727730

728731
ZEND_METHOD(Fiber, isStarted)
@@ -731,7 +734,7 @@ ZEND_METHOD(Fiber, isStarted)
731734

732735
ZEND_PARSE_PARAMETERS_NONE();
733736

734-
fiber = (zend_fiber *) Z_OBJ_P(getThis());
737+
fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
735738

736739
RETURN_BOOL(fiber->context.status != ZEND_FIBER_STATUS_INIT);
737740
}
@@ -742,7 +745,7 @@ ZEND_METHOD(Fiber, isSuspended)
742745

743746
ZEND_PARSE_PARAMETERS_NONE();
744747

745-
fiber = (zend_fiber *) Z_OBJ_P(getThis());
748+
fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
746749

747750
RETURN_BOOL(fiber->context.status == ZEND_FIBER_STATUS_SUSPENDED && fiber->caller == NULL);
748751
}
@@ -753,7 +756,7 @@ ZEND_METHOD(Fiber, isRunning)
753756

754757
ZEND_PARSE_PARAMETERS_NONE();
755758

756-
fiber = (zend_fiber *) Z_OBJ_P(getThis());
759+
fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
757760

758761
RETURN_BOOL(fiber->context.status == ZEND_FIBER_STATUS_RUNNING || fiber->caller != NULL);
759762
}
@@ -764,7 +767,7 @@ ZEND_METHOD(Fiber, isTerminated)
764767

765768
ZEND_PARSE_PARAMETERS_NONE();
766769

767-
fiber = (zend_fiber *) Z_OBJ_P(getThis());
770+
fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
768771

769772
RETURN_BOOL(fiber->context.status == ZEND_FIBER_STATUS_DEAD);
770773
}
@@ -776,7 +779,7 @@ ZEND_METHOD(Fiber, getReturn)
776779

777780
ZEND_PARSE_PARAMETERS_NONE();
778781

779-
fiber = (zend_fiber *) Z_OBJ_P(getThis());
782+
fiber = (zend_fiber *) Z_OBJ_P(ZEND_THIS);
780783

781784
if (fiber->context.status == ZEND_FIBER_STATUS_DEAD) {
782785
if (fiber->flags & ZEND_FIBER_FLAG_THREW) {
@@ -814,7 +817,7 @@ ZEND_METHOD(FiberError, __construct)
814817
zend_throw_error(
815818
NULL,
816819
"The \"%s\" class is reserved for internal use and cannot be manually instantiated",
817-
ZSTR_VAL(Z_OBJCE_P(getThis())->name)
820+
ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name)
818821
);
819822
}
820823

0 commit comments

Comments
 (0)