title: Thread synchronisation with SDL thread library
body: <p>I am attempting to write a thread safe task queue for multithreading in C++, using SDL2's threading library.</p>
  
  <p>The thread function which runs on all threads is as follows:</p>
  
  <pre><code>int threadFunc(void * pData)
  {
      ThreadData* data = (ThreadData*)pData;
      SDLTaskManager* pool = data-&gt;pool;
      Task* task = nullptr;
      while (true)
      {
          SDL_LockMutex(pool-&gt;mLock);
          while (!pool-&gt;mRunning &amp;&amp; pool-&gt;mCurrentTasks.empty())
          {
              //mutex is unlocked, then locked again when signal received
              SDL_CondWait(pool-&gt;mConditionFlag, pool-&gt;mLock);
              if (pool-&gt;mShuttingDown)
                  return 0;
          }
          //mutex is locked at this stage so no other threads can alter contents of deque
          //code inside if block should not be executed if deque is empty
          if (!pool-&gt;mCurrentTasks.empty())
          {
              /*out of range error here*/
              task = pool-&gt;mCurrentTasks.front();
              pool-&gt;mCurrentTasks.pop_front();
          }
  
          if (task != nullptr)
          {
              pool-&gt;notifyThreadWorking(true);
              data-&gt;taskCount++;
          }
          else
          {
              pool-&gt;stop();
              SDL_UnlockMutex(pool-&gt;mLock);
              continue;
          }
          SDL_UnlockMutex(pool-&gt;mLock);
          task-&gt;execute();
          SDL_LockMutex(pool-&gt;mLock);
          pool-&gt;notifyThreadWorking(false);
          pool-&gt;mCompleteTasks.push_back(task);
          SDL_UnlockMutex(pool-&gt;mLock);
          task = nullptr;
      }
      return 0;
  }
  </code></pre>
  
  <p>As you can see, according to the comments in the code, an out of range error occurs inside an if block, where the deque is empty. However, there is a check there to make sure that the code is only executed if the deque is not empty. The mutex is locked by SDL_CondWait so no other thread should be able to make changes to the deque, until that mutex is unlocked again.</p>
  
  <p>The producer code is as follows:</p>
  
  <pre><code>SDL_LockMutex(pool-&gt;mLock);
  for (int i = 0; i &lt; numTasks; i++)
  {
      pool-&gt;mCurrentTasks.push_back(new Task());
  }
  pool-&gt;mRunning = true;
  SDL_CondBroadcast(pool-&gt;mConditionFlag);
  SDL_UnlockMutex(pool-&gt;mLock);
  </code></pre>
  
  <p>The fact that the code inside the if block is being executed, shows that at the time <code>if (!pool-&gt;mCurrentTasks.empty())</code> is evaluated, the deque has member data, but not when it reaches <code>task = pool-&gt;mCurrentTasks.front();</code> By my understanding of mutex' this shouldn't be possible. How can this be?  </p>