facebookexperimental / facebookexperimental/libunifex

RAII in my async_mutex? It's more likely than you think.

Open
#387 2 comments 5 reactions 0 assignees View on GitHub
bug
Dominant language
C++
Stars
1.7k
Forks
210
PR merge metrics
No merged PRs in 30d

Description

Right now, usage patterns of async_mutex violate RAII in any case whatsoever, as locking the mutex (the "resource acquisition" part) is an async operation, and so cannot be done as part of a constructor (the "is initialization" part).

I think there will be no objections to this requiring a fix, so how would we do that?

I propose changing the signature of `async_lock` from `sender_of async_lock()` to `sender_of async_lock()`, where the asynchronously returned `unique_lock_like` object will unlock the mutex in it's destructor. This does mend the problem, as now initialization of this `unique_lock_like` object is precisely the same as acquiring the mutex.

The intention is for this new signature to be used as follows:

```
let_value(mtx.async_lock(), [](auto&) {
// safely work with the protected objects
};
```

A further expansion of this idea would be a rust-like `Mtx` class, which internally stores a `T`, and returns a reference to `T` from it's `async_lock` method. Although we won't ever have rust-like safety guarantees without borrowing, such a class would still prove to be useful in my opinion for a lot of use cases, simplifying the code and explicitly syntactically linking the protected object with the protecting synchronization primitive. With this, on could write code like

```
let_value(data_storage.async_lock(), [](auto& storage ) {
return do_other_async_work(storage->at("key"));
};
```
Which I think is more structured and less error-prone than the current status quo,
```
let_value(mtx.async_lock(), [&data_storage, &mtx]() {
return then(do_other_async_work(data_storage->at("key")),
[&mtx]() { mtx.unlock(); });
};
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.