You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In nativepg's connection pool I need a synchronization primitive that allows multiple waiters, and wake only one of them. Timers provided this, but a) they were removed as per my suggestion b) they are not the correct primitive.
I can't use async_event because it doesn't allow waking a single waiter, nor async_waker because it doesn't allow multiple waiters (also I don't need thread-safety).
I believe Capy should ship a type akin to std::condition_variable, as it does for std::mutex. I want to implement this type myself, but I want to have a design discussion first.
This is the API I believe would be best:
classasync_condition {
public:
impl_defined_awaitable wait();
voidnotify_one();
voidnotify_all();
};
// Wait until the predicate returns truetemplate <classPredicate>
task<results<>>
wait_until(async_condition&, Predicate);
Some important pieces:
async_condition intentionally doesn't have a 'notified' state, as opposed to async_event. The state must be maintained separately by the user. This allows for arbitrary states (e.g. 'wait for this list to become empty'), without having to keep async_event's internal state in sync (this has bitten me a lot of times).
In other languages (see Claude's research), as well as in std, condition variables are associated to a mutex. I've decided against it because async_condition is not thread-safe (like the other synchronization primitives). The mutex guards against race conditions between checking the predicate and suspending. This shouldn't happen here, as long as you don't co_await between checking and suspending. In multi-threaded contexts, you'd use a strand, so that should be safe.
Most of the time, you need to wait in a loop until the condition you're waiting for is true. This is because notify_xxx would post, so the condition can become false before the posted coroutine resumes. This is why wait_until is there.
I think you can implement async_event and async_mutex on top of this.
Claude kindly created a possible implementation. This hasn't been reviewed for correctness or tested yet - I'd like to validate the design before I do.
Before I take the time to create a full implementation with proper docs and tests, how does everyone feel about the design?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
In nativepg's connection pool I need a synchronization primitive that allows multiple waiters, and wake only one of them. Timers provided this, but a) they were removed as per my suggestion b) they are not the correct primitive.
I can't use
async_eventbecause it doesn't allow waking a single waiter, norasync_wakerbecause it doesn't allow multiple waiters (also I don't need thread-safety).I believe Capy should ship a type akin to
std::condition_variable, as it does forstd::mutex. I want to implement this type myself, but I want to have a design discussion first.This is the API I believe would be best:
Some important pieces:
async_conditionintentionally doesn't have a 'notified' state, as opposed toasync_event. The state must be maintained separately by the user. This allows for arbitrary states (e.g. 'wait for this list to become empty'), without having to keepasync_event's internal state in sync (this has bitten me a lot of times).std, condition variables are associated to a mutex. I've decided against it becauseasync_conditionis not thread-safe (like the other synchronization primitives). The mutex guards against race conditions between checking the predicate and suspending. This shouldn't happen here, as long as you don't co_await between checking and suspending. In multi-threaded contexts, you'd use a strand, so that should be safe.notify_xxxwould post, so the condition can become false before the posted coroutine resumes. This is whywait_untilis there.async_eventandasync_mutexon top of this.Claude kindly created a possible implementation. This hasn't been reviewed for correctness or tested yet - I'd like to validate the design before I do.
Before I take the time to create a full implementation with proper docs and tests, how does everyone feel about the design?
All reactions