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:

/////////////////////////////////////////////////////////////////////
Condition cond; // Previously instantiated.
bool loop = false; // This variable determine if the consumer should take the next iteration or wait until a thread calls SetLoop(true). Object my_variable; // A value used for comunicating producer and consumer. It's not a prerequisite to be set for an iteration to happen.

// This function is called by multiple threads.
void SetLoop(bool val)
{
        if(val != loop)
        {
                loop = val;
                if(loop)
                        cond.notify(); // Wake up consumer in case it was 
waiting.
        }
}

// This function is called by multiple threads.
bool GetLoop()
{
        return loop;
}

void MyConsumer()
{
        while(true)
        {
                synchronized(cond.mutex)
                {
                        if(loop == false)
                                cond.wait(); // Wait for producer or 
SetLoop(true).
                        
                        if(my_variable !is null)
                        {
                                /*
                                ...
Call private function 1. SetLoop(true/false) might be called here.
                                ...
                                */
my_variable = null; // Lock is useful here for setting my_variable.
                        }
                        
                        // These conditions are intentionally placed here.
                        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.
                        ...
                        */
                }
        }
}

void MyProducer()
{
        while(true)
        {
                if(/* Some other condition */)
                {
synchronized(cond.mutex) // Lock is useful here for setting my_variable.
                        {
                                my_variable = /* Some value */;
                                cond.notify(); // Wake up consumer in case it 
was waiting.
                        }
                }
        }
}
/////////////////////////////////////////////////////////////////////

Wouldn't wrapping all the lines in "SetLoop()" inside a "synchronized(cond.mutex)" statement produce a deadlock because it might be called by private functions 1 or 2? Should i only wrap cond.notify() or is it of no meaning in this case? Like this:

void SetLoop(bool val)
{
        if(val != loop)
        {
                loop = val;
                if(loop)
                {
                        synchronized(cond.mutex)
                                cond.notify(); // Wake up consumer in case it 
was waiting.
                }
        }
}

Synchronization of variable "loop" doesn't seem important in this case. Do you still recommend to use an extra mutex to set it? like this:

void SetLoop(bool val)
{
        synchronized(extra_mutex)
        {
                if(val != loop)
                {
                        loop = val;
                        if(loop)
                        {
                                synchronized(cond.mutex)
                                        cond.notify(); // Wake up consumer in 
case it was waiting.
                        }
                }
        }
}

void MyConsumer()
{
        //...
        if(loop == false)
                continue;
        else
        {
                synchronized(extra_mutex)
                        loop = false;
        }
        //...
}

Thank you guys so much for your time and your expertise.

Reply via email to