Author Topic: potential dead lock pattern in CC?  (Read 9120 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6034
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
potential dead lock pattern in CC?
« on: October 01, 2014, 12:53:21 pm »
Dead lock sometimes happens, I guess it is in CC.
I try to find some pattern which are the answers describe in What are common reasons for deadlocks?

Code
void cbThreadPool::AddTask(cbThreadedTask *task, bool autodelete)
{
  if (!task)
    return;

  wxMutexLocker lock(m_Mutex);

  m_tasksQueue.push_back(cbThreadedTaskElement(task, autodelete));
  m_taskAdded = true;

  // we are in batch mode, so no need to awake the idle thread
  // m_workingThreads < m_concurrentThreads means there are some threads in idle mode (no task assigned)
  if (!m_batching && m_workingThreads < m_concurrentThreads)
    AwakeNeeded();
}

In main thread:
In void Parser::OnBatchTimer(cb_unused wxTimerEvent& event)
Code
    bool send_event          = true;
    bool sendStartParseEvent = false;
    if (   !m_BatchParseFiles.empty()
        || !m_PredefinedMacros.IsEmpty() )
    {
        CC_LOCKER_TRACK_P_MTX_LOCK(ParserCommon::s_ParserMutex)

        ParserThreadedTask* thread = new ParserThreadedTask(this, ParserCommon::s_ParserMutex);
        TRACE(_T("Parser::OnBatchTimer(): Adding a ParserThreadedTask thread to m_Pool."));
        m_Pool.AddTask(thread, true); //once this function is called, the thread will be executed from the pool.

        if (ParserCommon::s_CurrentParser)
            send_event = false;
        else // Have not done any batch parsing yet -> assign parser
        {
            ParserCommon::s_CurrentParser = this;
            m_StopWatch.Start(); // reset timer
            sendStartParseEvent = true;
        }

        CC_LOCKER_TRACK_P_MTX_UNLOCK(ParserCommon::s_ParserMutex)
    }

Or
Code
bool Parser::Done()
{
    CC_LOCKER_TRACK_P_MTX_LOCK(ParserCommon::s_ParserMutex)

    bool done = m_BatchParseFiles.empty()
                && m_PredefinedMacros.IsEmpty()
                && !m_NeedMarkFileAsLocal
                && m_Pool.Done();

    CC_LOCKER_TRACK_P_MTX_UNLOCK(ParserCommon::s_ParserMutex)

    return done;
}

In worker thread:
int ParserThreadedTask::Execute()
Code
    CC_LOCKER_TRACK_P_MTX_UNLOCK(m_ParserMutex);

    if (m_Parser->m_IgnoreThreadEvents)
        m_Parser->m_IsFirstBatch = true;

    TRACE(_T("ParserThreadedTask::Execute(): Parse source files"));
    while (!batchFiles.empty())
    {
        TRACE(_T("-ParserThreadedTask::Execute(): Parse %s"), batchFiles.front().wx_str());
        m_Parser->Parse(batchFiles.front()); // bool isLocal = true, bool locked = false
        batchFiles.pop_front();
    }

    CC_LOCKER_TRACK_P_MTX_LOCK(m_ParserMutex)

All the patterns are:
Code
lock the parser mutex
lock the pool
release the pool
release the parser mutex

Is it the bad code pattern which may cause dead lock?

EDIT
: It looks like the answer is NO. ;)

« Last Edit: October 01, 2014, 02:28:17 pm by ollydbg »
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.