lundi 27 septembre 2021

Lock/unlock std::unique_lock in different functions

I'm writing a program that uses a condition variable as such:

bool flag;
std::mutex mtx;
std::condition_variable cond;

{
  std::unique_lock<std::mutex> lock(mtx);
  cond.wait(lock, [&]{ return flag; });

  // ... do some stuff
  // ... do some more stuff

  flag = false;

} // lock unlocked here

Now I'm faced with the problem that "do some stuff" and "do some more stuff" are actually implemented in two separate callback functions invoked one after the other from somewhere else, i.e.:

void callback1() {
   std::unique_lock<std::mutex> lock(mtx);
   cond.wait(lock, [&]{ return flag; });

   // ... do some stuff
} // ERROR! lock unlocked too early

void callback2() {
   // ... do some more stuff
  flag = false;
} // lock should be unlocked here

How can I solve this issue? I could encapsulate both callbacks in some object that holds the lock as a member variable but that seems to me like it goes against the intended semantics of std::unique_lock.

EDIT: more context:

Someone else has written a class Foo that looks as follows:

class Foo
{
public:
  void bar() {
    before_bar_callback();

    // ...
    
    after_bar_callback();
  }

private:
  virtual void before_bar_callback() {}
  virtual void after_bar_callback() {}
};

I can't modify Foo::bar and it runs in a separate thread. I would like to wait on a condition variable in before_bar_callback and then set flag = false and unlock the associated lock in after_bar_callback.

Aucun commentaire:

Enregistrer un commentaire