Repository navigation
test(xpp): verify .await() inside spawned fns + correct spawn.h docs - #86
Merged
Merged
Conversation
Empirically settles the 'can you .await() inside xpp::spawn?' question that came up while evaluating a WaitScope fiber design (explored and rejected — the re-entrant park model already delivers the observable semantics; see the deleted todos/wait-scope-fiber-await.md discussion). Four new tests in spawn_test.cpp: - AwaitInsideSpawnedFn — a spawned fn .await()s a channel recv; a timer feeds the channel while the fn is parked. Verifies park() re-enters the event loop: the world keeps turning while the fn waits. - SequentialAwaitsInsideSpawnedFn — two park/resume cycles in one fn (each .await() parks, gets fed by its own timer, resumes). - AwaitTimerInsideSpawnedFn — .await() on a timer promise directly. - AwaitCrossChainInsideSpawnedFn — chain A awaits a promise that chain B resolves after a timer: cross-chain .await() with both chains spawned on the same loop. The old spawn.h doc said .await() inside a spawned fn 'would block unless already inside a fiber' — misleading. Corrected to state the verified semantics: usable (parks the step's stack while re-entering the loop), idiomatic forms remain .then()/co_await, and documenting the real deadlock boundary (awaiting anything that only resolves after the fn returns, e.g. its own JoinHandle — circular wait). Verified: spawn_test 14/14 (ASan), TSan 0 warnings, related promise suites green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Empirically settles the "can you
.await()insidexpp::spawn?" question with tests, and corrects thespawn.hdocs that said it "would block unless already inside a fiber" — which was misleading.Verified semantics (4 new tests)
AwaitInsideSpawnedFn.await()s a channel recv; a timer feeds the channel while the fn is parked — park() re-enters the event loop, the world keeps turningSequentialAwaitsInsideSpawnedFn.await()parks, gets fed by its own timer, resumes)AwaitTimerInsideSpawnedFn.await()on a timer promise directlyAwaitCrossChainInsideSpawnedFn.await(), both chains spawned on the same loopDoc correction (spawn.h)
The old text discouraged
.await()inside spawned fns. The corrected doc states:park()runsX_RUN_ONCEuntil woken) — timers, I/O, other chains keep progressing.then()chains (C++11) /co_await(C++20) — waker-driven, no parked stack — but plain sequential.await()works when convenientContext: this came out of evaluating a WaitScope-fiber design (make
.await()a true suspension via a loop fiber). The design was explored and rejected — the re-entrant park model already delivers the observable semantics; the fiber design's costs (livelock traps, lifecycle dance) outweighed its aesthetic benefit. The tests + doc correction are the durable output of that exploration.Verification