← Back to context

Comment by mgaunard

3 months ago

You only achieved a deadlock by re-introducing mutexes.

Given:

    Something someting;
    async_mutex mtx;
    void my_critical_section(Data&);

1:

    await mtx.lock();
    my_critical_section(something);
    await mtx.unlock();

2:

    auto my_locked_critical_section() {
      await mtx.lock();
      my_critical_section(something);
      await mtx.unlock();
    }
    ...    
    await my_locked_critical_section(something);

3:

    auto locked(auto mtx, auto critical_section) {
      await mtx.lock();
      critical_section();
      await mtx.unlock();
    }

    ...    
    await locked(mtx, [&]{ my_critical_section(something); });

4:

    template<class T>
    struct synchronized {
       async_mutex mtx;
       T data;
       auto async_visit(auto fn) { locked(mtx, [fn,&data]{ fn(data); }); }
    };

    synchronized<Something> something;
    await something.async_visit([](Something& data) { my_critical_section(something); });

If 1 is a mutex, at which point it stops being a mutex? Note that 4 is my initial example.

  • it's a mutex iff it's acquiring a resource exclusively.

    which you don't need to do for synchronization of coroutines since you can control in which order things are scheduled and whether that's done concurrently or not.