Skip to content
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

introduce unifex::async_resource #475

Draft
wants to merge 141 commits into
base: main
Choose a base branch
from

Conversation

janondrusek
Copy link
Contributor

  • async_destroy CPO
  • returns a ptr-like object

Eric Niebler and others added 30 commits May 21, 2021 09:53
…/unstable

Merge from unstable to broken-stdlib
This commit implements scheduler affinity -- aka "sticky" scheduling -- in `unifex::task<>`. The idea is that it is impossible for a child operation to cause the current coroutine to resume on the wrong execution context.

* `task<>`-based coroutines track and propagate the current scheduler
* `at_coroutine_exit` remembers current scheduler from when the cleanup action is scheduled
* `schedule` always returns an instance of `sender_for<schedule, the_sender>`,
  which is also a `scheduler_provider`
* scheduler affinity when co_await-ing senders in a `task<>`-returning coroutine
* scheduler affinity when co_await-ing awaitables in a `task<>`-returning coroutine
* awaitables and senders that are `blocking_kind::always_inline` don't get a thunk
* More senders and awaitables support compile-time blocking queries
* `co_await schedule(sched)` is magic in a `task<>`-returning coroutine: it changes execution
  context and schedules a cleanup action to transition back to the original scheduler
…/create-sender

add unifex::create for trivially wrapping a C-style async API, fixes facebookexperimental#294
janondrusek and others added 8 commits September 27, 2022 19:20
* simpler than `unifex::v1::async_scope` (`nest()` and `join()`)
* does not support cancellation

Co-authored-by: Ian Petersen <[email protected]>

Co-authored-by: Ian Petersen <[email protected]>
PR facebookexperimental#454 missed including `<unifex/continuations.hpp>` in
`when_all_range.hpp` so let's fix that.
The existing operation state for `let_value_with` assumes that its
*Sender* will always be an rvalue; this diff fixes the operation state's
constructor to support lvalue *Senders*.
`unifex::nest()` is a CPO that delegates to either a `tag_invoke`
customization taking a *Sender* and a "scope" reference, or to a
member function on the given scope that takes a *Sender*.  This
diff wires `unifex::nest()` to the `nest()` member function on
`v2::async_scope` and to the `attach()` member function on
`v1::async_scope`.
…tal#470)

This diff introduces a new algorithm, `unifex::spawn_detached()`.
`spawn_detached` takes a sender, an "async scope", and an optional
allocator.  It nests the sender in the scope with `unifex::nest`,
allocates and operation state using the allocator, and starts that
operation.  The given async scope may be anything that `nest()`
supports, which currently includes both `v1::async_scope` and
`v2::async_scope`.
With the introduction of `unifex::nest()` and
`unifex::spawn_detached()`, we can simplify the implementation of
`v1::async_scope`.  This diff changes its `detached_spawn` to delegate
to `unifex::spawn_detached()`.
@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Nov 4, 2022
jesswong and others added 6 commits November 29, 2022 16:13
…acebookexperimental#477)

* Disable continuation visitations by default for binary size savings

* Add unifex prefix to macro and fix async_trace

* Fix unused variable error

* Change ordering of field initializations

* Address comments
* gcc 9,10
* clang 10,11,12
* rm absl and related polyfills

* optional
* utility
* variant
This diff adds some `//` comments to the ends of some lines and then
runs the result through `clang-format`.
…l#483)

When trying to nest a `let_value_with_stop_token()` *Sender* inside a
`unifex::v2::async_scope`, I discovered there were problems checking the
constraints on a `const Sender&` when `Sender` was a
`let_value_with_stop_token` *Sender* constructed with a `mutable`
lambda.

This diff fixes the above scenario and includes a regression test.  The
fixes include:
 - fixing the type calculations on `SuccessFactory` (e.g. we invoke an
   lvalue reference not an rvalue reference)
 - correcting the `noexcept` calculations (e.g. although we *construct*
   our copy of the `SuccessorFactory` in a value category-sensitive way,
   we always *invoke* the factory as a mutable lvalue)
 - standardizing value category casts (i.e. using `std::move()` for
   moves and `static_cast<DestType&&>()` for forwards)
 - adding some `static_assert`s to confirm the validity of the above
   fixes
 - made the operation state immovable
…mental#484)

While writing `unifex::spawn_future()`, I discovered that waiting until
the destructor of the `v2::async_scope`'s `nest()` operation to drop the
scope reference is too late (it led to hangs).  This diff adds an
internal receiver to the nest operation so we can detect when the
operation is complete (which is likely before the operation state is
destroyed) and drop the reference as soon as we reach that state.
@janondrusek janondrusek force-pushed the broken-stdlib branch 4 times, most recently from 80cb272 to 77bc100 Compare February 1, 2023 23:33
Copy link
Contributor

@ispeters ispeters left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More later…

include/unifex/async_destroy.hpp Outdated Show resolved Hide resolved
include/unifex/async_resource.hpp Outdated Show resolved Hide resolved
include/unifex/async_resource.hpp Outdated Show resolved Hide resolved
include/unifex/async_resource.hpp Outdated Show resolved Hide resolved
include/unifex/async_resource.hpp Outdated Show resolved Hide resolved
include/unifex/async_resource.hpp Outdated Show resolved Hide resolved
include/unifex/async_resource.hpp Outdated Show resolved Hide resolved
include/unifex/async_resource.hpp Outdated Show resolved Hide resolved
include/unifex/async_resource.hpp Show resolved Hide resolved
include/unifex/async_resource.hpp Outdated Show resolved Hide resolved
- async_destroy CPO
- returns a `unique_ptr`-like object
@ericniebler
Copy link
Collaborator

Hi all! :-)

### `async_resource`

Provides _async RAII_ programming idiom. `async_resource_ptr<T>` is like
a `std::unique_ptr<T>` except that `async_resource_ptr<>`'s destructor destroys
its `T` asynchronously, in constrast to `unique_ptr<>`'s destructor's
synchronous invocation of `delete p_`. `async_resource` removes the need for
manual lifetime management of a `Resource` protected by an `async_scope` and
should be preferred over `async_scope`, if there is a need for one.

1. explicitly supports parent / child relationship modeled as a tree
2. allows for subtree removal / swap
3. each `Resource` managed by `async_resource` has an associated, managed _inner_
   `async_scope` without an explicit option to `join()`

I'm trying to wrap my head around the implications of this change. IIUC, "async resource" is a concept, and that there are generic algorithms/utilities that get constrained with it, and multiple concrete types that model the concept.

One such generic utility is async_resource_ptr, which is somehow simpler to use than async_scope. Can you point me to a before/after showing how code gets simpler with async_resource_ptr?

@janondrusek janondrusek changed the base branch from broken-stdlib to main May 11, 2023 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.