title: read/write lock implementation using mutex only?
body: <p>I was trying to implement read/write lock using mutex only (just for learning). Just when i thought i have covered all corner cases (as the program worked with variety of combinations), i have realized, i ignored the fact (as it worked in ubuntu) that, the mutex should be freed by the owner of the thread. Below is my implementation,</p>
  
  <pre><code>class rw_lock_t{
  
      int NoOfReaders;
      int NoOfWriters, NoOfWritersWaiting;
      pthread_mutex_t class_mutex;
      pthread_cond_t class_cond;
      pthread_mutex_t data_mutex;
  
  public:
  
      rw_lock_t()
      : NoOfReaders(0),
        NoOfWriters(0), NoOfWritersWaiting(0)
      {
              pthread_mutex_init(&amp;class_mutex, NULL);
              pthread_mutex_init(&amp;data_mutex, NULL);
              pthread_cond_init(&amp;class_cond, NULL);
      }
      void r_lock()
      {
              pthread_mutex_lock(&amp;class_mutex);
              //while(NoOfWriters!=0 || NoOfWritersWaiting!=0) //Writer Preference
              while(NoOfWriters!=0)
              {
                      pthread_cond_wait(&amp;class_cond, &amp;class_mutex);
              }
              if(NoOfReaders==0)
              {
                      pthread_mutex_unlock(&amp;class_mutex);
                      pthread_mutex_lock(&amp;data_mutex);
                      pthread_mutex_lock(&amp;class_mutex);
                      NoOfReaders++;
                      pthread_mutex_unlock(&amp;class_mutex);
              }
              else if(NoOfReaders&gt;0) //Already Locked
              {
                      NoOfReaders++;
                      pthread_mutex_unlock(&amp;class_mutex);
              }
      }
      void w_lock()
      {
              pthread_mutex_lock(&amp;class_mutex);
              NoOfWritersWaiting++;
              while(NoOfReaders!=0 &amp;&amp; NoOfWriters!=0)
              {
                      pthread_cond_wait(&amp;class_cond, &amp;class_mutex);
              }
              pthread_mutex_unlock(&amp;class_mutex);
  
              pthread_mutex_lock(&amp;data_mutex);
              pthread_mutex_lock(&amp;class_mutex);
              NoOfWritersWaiting--; NoOfWriters++;
              pthread_mutex_unlock(&amp;class_mutex);
      }
      void r_unlock()
      {
              pthread_mutex_lock(&amp;class_mutex);
              NoOfReaders--;
              if(NoOfReaders==0)
                      pthread_mutex_unlock(&amp;data_mutex);
              pthread_mutex_unlock(&amp;class_mutex);
              pthread_cond_signal(&amp;class_cond);
      }
      void w_unlock()
      {
              pthread_mutex_lock(&amp;class_mutex);
              NoOfWriters--;
              if(NoOfWriters==0)
                      pthread_mutex_unlock(&amp;data_mutex);
              pthread_mutex_unlock(&amp;class_mutex);
              pthread_cond_signal(&amp;class_cond);
      }
  };
  </code></pre>
  
  <p>My question now is, what is the best way (minimal change) to rectify. Semaphore is definitely the idle choice, but I thought of solutions as below</p>
  
  <p>Solution#1</p>
  
  <p>1) I will have a dedicated thread, just to lock/unlock the mutex for read case.</p>
  
  <p>2) This thread will be waiting on a condition variable to get signal from r_lock or r_unlock.</p>
  
  <p>3) r_lock and r_unlock will instead of doing "pthread_mutex_lock/unlock(&amp;data_mutex);", will signal the dedicated thread to lock instead.</p>
  
  <p>4) I have to remember many facts for this implementation,</p>
  
  <ul>
  <li><p>The signaling and actual locking are two different events, so might need synchronization.</p></li>
  <li><p>Will need a mutex+condVariable+thread and more synchronization extra.</p></li>
  </ul>
  
  <p>Update: Solution#2</p>
  
  <p>1) The thread who did the actual locking will keep its tid globally.</p>
  
  <p>2) whenever a thread unlocks will make sure the check equality with the global tid.</p>
  
  <p>3) If matches will wait for "NoOfReaders==0" condition and unlock it.</p>
  
  <p>So, is there a better way in which the program can be rectified.</p>