Using Forced State Variables

I design the asynchronous registrar class as follows. However, I'm not sure if I am using the boost condition variable correctly. Can anyone comment on this? Here the processLogEntry method is a stream function, and I use boost here.

void LogWriter::stopThread()
{
    mStop = true;
    mCond.notify_one();
    mThread->join();
}   

void LogWriter::processLogEntry()
{
    while(!mStop)
    {
        boost::mutex::scoped_lock lock(mMutex);
        mCond.wait(lock);
        while(!q.empty())
        {
            // process begins
        }
    }
}

void LogWriter::addLogEntry()
{
    boost::mutex::scoped_lock lock(mMutex);
    // add it in the queue
    mCond.notify_one();
}
+3
source share
1 answer

As already indicated, you must either make mStopatomic or protect all its appeals with the help of the mutex. Forget about volatile, this does not apply to your goals.

In addition, when waiting for a state variable, the call waitmay return even if the notification functions were not called (these are the so-called side awakenings). Therefore, you need to protect calls wait.

void LogWriter::stopThread()
{
    {
        boost::mutex::scoped_lock lock(mMutex);
        mStop = true;
        mCond.notify_one();
    }
    mThread->join();

}   

void LogWriter::processLogEntry()
{
    for(;;) {
        boost::mutex::scoped_lock lock(mMutex);
        // We wait as long as we're not told to stop and
        // we don't have items to process
        while(!mStop && q.empty()) mCond.wait(lock);

        // Invariant: if we get here then
        // mStop || !q.empty() holds

        while(!q.empty())
        {
            // process begins
        }

        if(mStop) return;
    }
}
+3
source

All Articles