title: Pthread locking
body: <p>I have created MutexCondition class like this</p>
  
  <pre><code>/*MutexCondtion.h file*/
  #ifndef MUTEXCONDITION_H_
  #define MUTEXCONDITION_H_
  
  #include &lt;pthread.h&gt;
  #include &lt;stdio.h&gt;
  
  class MutexCondition {
  
  private:
      bool init();
      bool destroy();
  
  protected:
      pthread_mutex_t m_mut;
      pthread_cond_t m_con;
  
  public:
      MutexCondition(){
          init();
      }
      virtual ~MutexCondition(){
          destroy();
      }
  
      bool lock();
      bool unLock();
      bool wait();
      bool signal();
  
  };
  #endif /* MUTEXCONDITION_H_ */
  </code></pre>
  
  <p>MutexCondtion.cpp file</p>
  
  <pre><code>#include "MutexCondition.h"
  
  bool MutexCondition::init(){
      printf("MutexCondition::init called\n");
      pthread_mutex_init(&amp;m_mut, NULL);
      pthread_cond_init(&amp;m_con, NULL);
      return true;
  }
  
  bool MutexCondition::destroy(){
      pthread_mutex_destroy(&amp;m_mut);
      pthread_cond_destroy(&amp;m_con);
      return true;
  }
  
  bool MutexCondition::lock(){
      pthread_mutex_lock(&amp;m_mut);
      return true;
  }
  
  bool MutexCondition::unLock(){
      pthread_mutex_unlock(&amp;m_mut);
      return true;
  }
  
  bool MutexCondition::wait(){
      pthread_cond_wait(&amp;m_con, &amp;m_mut);
      return true;
  }
  
  bool MutexCondition::signal(){
      pthread_cond_signal(&amp;m_con);
      return true;
  }
  </code></pre>
  
  <p>And I created a WorkHandler which extends the MutexCondition </p>
  
  <pre><code>#ifndef WORKHANDLER_H_
  #define WORKHANDLER_H_
  
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;queue&gt;
  #include &lt;pthread.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;list&gt;
  
  #include "MutexCondition.h"
  #include "Work.h"
  
  using namespace::std;
  
  class WorkHandler: MutexCondition {
  
  private:
      int m_maxThreads;
  
      queue&lt;Work*&gt; m_workQueue;
      list&lt;pthread_t*&gt; m_workThreadList; //Just thread IDs
  
      pthread_t **m_workThreads;
  
      void workLoop();
      bool initThreads();
      void insertWork(Work *work);
      Work* getWork();
  
  protected:
      static void* runWorkThread(void* delegate);
  
  public:
      WorkHandler(int maxThreads);
      virtual ~WorkHandler();
  };
  
  #endif /* WORKHANDLER_H_ */
  </code></pre>
  
  <p>WorkHandler.cpp file</p>
  
  <pre><code>#include "WorkHandler.h"
  
  WorkHandler::WorkHandler(int maxThreads) {
      // TODO Auto-generated constructor stub
      m_maxThreads = maxThreads;
      initThreads();
  }
  
  WorkHandler::~WorkHandler() {
      // TODO Auto-generated destructor stub
  }
  
  void* WorkHandler::runWorkThread(void *delegate){
      printf("WorkHandler::runWorkThread called\n");
  
      WorkHandler *ptr = reinterpret_cast&lt;WorkHandler*&gt;(delegate);
      ptr-&gt;workLoop();
      return NULL;
  }
  
  void WorkHandler::workLoop(){
      printf("WorkHandler::workLoop called\n");
  
      //WorkHandler *ptr = reinterpret_cast&lt;WorkHandler*&gt;(delegate);
  
      while(1){
          Work *work = getWork();
      }
  }
  
  bool WorkHandler::initThreads(){
  
      for(int i=0; i &lt; m_maxThreads; i++){
          pthread_t *thread(new pthread_t);
          m_workThreadList.push_back(thread);
  
          if(pthread_create(thread, NULL, runWorkThread, reinterpret_cast&lt;void *&gt;(this))!=0){
              perror("InitThreads, pthread_create error \n");
              return false;
          }
  
          pthread_detach(*thread);
      }
  
      return true;
  }
  
  void WorkHandler::insertWork(Work* w){
      printf("WorkHandler::Thread %d insertWork locking\n", pthread_self());
      lock();
      printf("WorkHandler::insertWork Locked and inserting int queue \n");
      m_workQueue.push(w);
      signal();
      unLock();
  }
  
  Work* WorkHandler::getWork(){
      printf("WorkHandler::getWork locking\n");
      lock();
      printf("WorkHandler::getWork locked\n");
      while(m_workQueue.empty()){//Need while instead of If
          printf("WorkHandler::getWork waiting...\n");
          wait();
      }
      Work *work = m_workQueue.front();
      printf("WorkHandler::getWork got a job\n");
      m_workQueue.pop();
      unLock();
  
      return work;
  }
  </code></pre>
  
  <p>The problem is that I have locked the mutex variable in the getWork() function like this</p>
  
  <pre><code>    printf("WorkHandler::getWork locking\n");
      lock();
      printf("WorkHandler::getWork locked\n");
  </code></pre>
  
  <p>However, if I see the log statements then all threads printed these two log statements and I think this is a problem. I am not putting anything into the queue so the first thread should wait the condition variable to be signaled and it works ok. But how come other thread can enter the area behind the lock although the first thread locked and has not called the unlock() function. </p>
  
  <p>I was wondering if this is working correctly. Pleas let me know if you guys can see anything I need to fix. Thanks in advance.</p>