Thread Safetry Analysis with async locks + coroutines

Hello, I have an “async” lock that’s signature looks like this:

class Mutex {
  Future<> Lock();
  void Unlock();

I’d like to add thread safety annotations here: Thread Safety Analysis — Clang 18.0.0git documentation Future is an awaitable, so usage looks like:

co_await mutex.Lock();
// do thing...

I’d like the thread safety analysis to be able to warn me if I did this:

mutex.Lock(); // forgot to await (okay this can be solved by [[no_discard]] on the future)

or alternatively:

auto l = mutex.Lock(); // need to co_await to actually acquire the lock!

Untimately, I’d like to have a RAII lock holder, but I really can’t figure something like this out:

co_await MutexLock::Guard(mutex);
// can do thing in scope...

I’ve taken a stab at this here: Compiler Explorer

I believe I’ll need some custom coroutine awaitables with the annotations if it’s possible to get this working. I seem to not be able to “transfer” the scoped lockable over to a return object and keep thread safety happy. Does anyone have tips for this?

To be clear, this isn’t an academic exercise, but I’d like to do this for a powered application, these locks suspend the current fiber until the lock is acquired instead of traditional blocking a thread.

Thank you for your reading and consideration!

1 Like

CC @aaronpuchert who might have ideas