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

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5242
  • 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: [Select]
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: [Select]
   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: [Select]
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: [Select]
   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: [Select]
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.