On Tue, 14 May 2013 13:59:51 -0400, Heinz <thor...@gmail.com> wrote:

Guys, this is a precise example of what i'm trying to do. You'll notice that there're 2 ways of waking up the consumer:

2 things:

1. D mutex locks are re-entrant.  That is, you can do:

synchronized(mutex)
{
   synchronized(mutex)
   {
      ...
   }
}

and all is fine.

2. The condition logic in your code is wrong. The condition/mutex protects the messages being sent to the consumer.

It seems that you have two messages (which is OK):

 - my_variable is present, needs to be processed
- Run function 2 (flag loop == run function 2), set from inside the consumer, and some undisclosed threads. I find this logic rather dangerous, but it is your app, I have no idea of the real meaning :)

So I would do it like this (names TBD based on your real use case)

void SetLoop(bool yesOrNo)
{
   synchronized(cond.mutex)
   {
       if((loop = yesOrNo) == true)
            cond.notify();
   }
}

void MyConsumer()
{
        while(true)
        {
                Object _my_variable = null;
                synchronized(cond.mutex)
                {
while(!loop && my_variable is null) // always wait for *real* messages to be set
                                cond.wait();
                        _my_variable = my_variable;
                        my_variable = null; // consume
                }

                // process local consumed copy of _my_variable *outside* of lock
                if(_my_variable !is null)
                {
                        /*
                        ...
                        Call private function 1. SetLoop(true/false) might be 
called here.
                        ...
                        */
                }
                        
                // These conditions are intentionally placed here.
                synchronized(cond.mutex)
                {
                        if(loop == false)
continue; // Jump to next iteration. Please note that cond.mutex gets released and reaquired in the next iteration.
                        else
loop = false; // Reset waiting on every iteration. Can be modified by private function 2 below.
                }
                        
                /*
                ...
                Call private function 2. SetLoop(true/false) might be called 
here.
                ...
                */
        }
}

Then everything should be good. I'd also add a "SetMyVariable" function too, akin to SetLoop.

-Steve

Reply via email to