-
Notifications
You must be signed in to change notification settings - Fork 226
Scope Senders & Asynchronous Objects #1790
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
Draft
RobertLeahy
wants to merge
10
commits into
NVIDIA:main
Choose a base branch
from
RobertLeahy:async_object
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Conversation
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
RobertLeahy
commented
Jan 25, 2026
| // sending the completion signal may end our lifetime, which means | ||
| // we shouldn't send references into ourselves, therefore we move | ||
| // all the non-references onto the stack | ||
| std::remove_cvref_t<decltype(tuple_or_monostate)>( |
Contributor
Author
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can throw.
Certain algorithms, for example when_all, must store the completions of child operations and then later examine or forward them. The typical way of doing this is via decay-copy into a tuple, but this erases the reference-ness of values and errors. The class template added by this commit, exec:: storage_for_completion_signatures, makes it convenient to store, examine, and forward the completions of some asynchronous operation, while also being reference-aware.
Type alias for the type returned by std::forward_like.
stdexec::let_value performs two functions: - Persisting the values sent by the predecessor, and - Predicating the successor on those persisted values Which leaves space for a lower level primitive: One which simply predicates a successor sender on the values sent by a predecessor. That lower level primitive is exec::invoke.
Adds concepts which deal with exit scope senders. An exit scope sender performs the clean up/rollback operations necessary to leave a "scope." As such an exit scope sender must (in addition to being a sender): - Send exactly stdexec::set_value_t() - Be nothrow connectable - Be nothrow movable - Be nothrow decay-copyable Note that in some sense an exit scope sender is analogous to a destructor.
Adds concepts which deal with enter scope senders. Whereas an exit scope sender performs the operations necessary to leave a scope, an enter scope sender performs the operations necessary to enter a scope. Just entering a scope is insufficient, however, as if a scope is entered it must be exited. Therefore enter scope senders not only perform the actions which must be taken to enter a scope, but also complete with a sender which undoes those actions, i.e. all enter scope senders are a higher-order sender.
An algorithm which combines N enter scope senders into a single enter scope sender which enters the scopes represented by each of its children in parallel, i.e. the scopes are entered in no particular order, as if by stdexec::when_all.
Algorithm which accepts an enter scope sender, and a sender to run within the scope represented by the enter scope sender, respectively. The resulting operation: 1. Enters the scope represented by the enter scope sender 2. Runs the operation represented by the other sender 3. Stores the completion of the above 4. Exits the scope using the exit scope sender yielded by the operation in step 1 5. Yields the completion stored in step 3
Adds the concepts which deal with asynchronous objects. An asynchronous object is an object whose constructor and destructor are asynchronous operations (as opposed to regular, synchronous object which have constructors and destructors which are regular, synchronous functions). Whereas senders are a fully-curried asynchronous function the concept of an asynchronous object embodied by the concepts in this commit is a fully-curried asynchronous constructor. The particular form of the aforementioned is a unary invocable whose: - Sole argument is a pointer to storage whereat the asynchronous object shall be placed - Returned value is an enter scope sender which constructs the object (asynchronously) when the scope is entered, and destroys the object (asynchronously) when the scope is exited
Enables consumption of asynchronous objects. Accepts an invocable, and N asynchronous objects. Forms an operation which, when connected: 1. Provides the asynchronous objects with storage in its operation state 2. Passes all enter scope senders obtained in step 1 to exec:: enter_scopes to combine them 3. Connects the resulting enter scope sender And when started: 1. Starts the enter scope sender which was connected in step 3 above 2. If the operation started in step 1 sends error or stopped, completes immediately with that completion, otherwise passes a reference to all of the newly-constructed objects to the invocable, obtaining a sender 3. Connects and starts the sender obtained in step 2 4. Upon the completion of that operation, stores the completion thereof 5. Connects and starts the exit scope sender which destroys the objects constructed in step 1 6. Upon the completion of that operation, ends the overall operation with the completion stored in step 4
Adaptor which transforms a regular, synchronous object into an asynchronous object.
ad51ce3 to
98869bd
Compare
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.
Please do not squash.
Implementation of P3955 - It's Scopes All the Way Down.