1
votes

I'm new to the boost threads library. I have a situation where I acquire a scoped_lock in one function and need to wait on it in a callee.

The code is on the lines of:

class HavingMutex
{
   public:
   ...
   private:
   static boost::mutex m;
   static boost::condition_variable *c;
   static void a();
   static void b();
   static void d();
}

void HavingMutex::a()
{
   boost::mutex::scoped_lock lock(m);
   ...
   b()          //Need to pass lock here. Dunno how !
}

void HavingMutex::b(lock)
{
    if (some condition)
    d(lock) // Need to pass lock here. How ?
}

void HavingMutex::d(//Need to get lock here)
{
    c->wait(lock); //Need to pass lock here (doesn't allow direct passing of mutex m)
}

Basically, in function d(), I need to access the scoped lock I acquired in a() so that I can wait on it. (Some other thread will notify).

Any help appreiciated. Thanks !

1
You have a lot of members and methods defined as static. Is that really what you want? This mutex is a property of the class itself? I suppose it's not unheard of, but in my experience makes for a more challenging metaphor. Could you/should you just use the mutex to protect some of the instance members instead? - Brian Cain
@BrianCain Actually I'm protecting some members of the class (that I haven't shown here) using the mutex. And, this design is kinda fixed. I just need a way wait from d(). - Mathangi Venkatesan
Well, you state that the design is fixed but what if it's why you're here in the first place? Sometimes the hard answer is the right answer. To better help you, can you describe what it is the HavingMutex class is supposed to do? - Brian Cain
Basically, a() takes 1st element in a dataStructure (that's a static member of the class) and passes that to b(). b() may modify it. In the meantime, another thread modifies this datastructure and something else that b()modifies. When c() waits, its this other thread that signals it. @BrianCain What I'm wondering is merely about the syntax. How can I pass a reference of scoped_lock to c() ? - Mathangi Venkatesan
I understand that your question is about the syntax, but what I've found is that when I can't do something in boost, it's almost always because if boost let me do that it would blow up in my face. So, rather than answer "how can I pass a reference of scoped_lock?" I'd prefer to ask another question: b() may modify some class members and then signal a thread or thread(s) currently wait()ing in the c() method? - Brian Cain

1 Answers

0
votes

Have you tried simple reference? According to boost 1.41 documentation at http://www.boost.org/doc/libs/1_41_0/doc/html/thread/synchronization.html it should be all that is required. ...

     void HavingMutex::a()
     {
        boost::mutex::scoped_lock lock(m);
        ...
        b(lock);
     }

     void HavingMutex::b(boost::mutex::scoped_lock &lock)
     {
         if (some condition) // consider while (!some_condition) here
           d(lock); 
     }

     void HavingMutex::d(boost::mutex::scoped_lock &lock)
     {
         c->wait(lock);
     }

     void HavingMutex::notify()
     {
         // set_condition;
         c->notify_one();
     }

Also in boost example they have while cycle around wait. Wait could be interrupted in some cases by system itself, not really you got the lock.

I suggest you reconsider having all methods static with static members also. Instead create them as normal members, and create one global object.