title: Conditional variable and rwlock deadlock
body: <p>I have a simple threaded program which use a conditional variable and a rwlock. I've been staring at it for hours trying different approaches. The problem is that a thread or more stops at the rwlock after a while although it is not locked for writing. Maybe I miss something about how those locks work or how they are implemented.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;time.h&gt;
  #include &lt;math.h&gt;
  #include &lt;unistd.h&gt;
  
  //global variables
  pthread_mutex_t mutex;
  pthread_cond_t cond;
  pthread_rwlock_t rwlock;
  int counter;
  int listLength = 1;
  
  void* worker(void* arg){
     do {
        usleep(200);
        printf("Before rwlock\n");
        pthread_rwlock_rdlock(&amp;rwlock);
        printf("Before mutex\n");
        pthread_mutex_lock(&amp;mutex);
        printf("Afer mutex\n");
        counter++;
        //signal the main
        if (counter == 5 ||
                 (listLength &lt; 5 &amp;&amp; counter == listLength)){
            printf("Signal main\n");
            pthread_cond_signal(&amp;cond);
            counter = 0;
        }
        pthread_mutex_unlock(&amp;mutex);
        pthread_rwlock_unlock(&amp;rwlock);
     } while(listLength != 0);
  
     return NULL;
  }
  
  
  int main(int argc, char* argv[]){
      if (argc != 2){
          perror("Invalid number of args");
          exit(1);
      }
      //get arguments
      int workers = atoi(argv[1]);
  
      //initialize sync vars
      pthread_rwlockattr_t attr;
      pthread_rwlockattr_setkind_np(&amp;attr,
              PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
      pthread_mutex_init(&amp;mutex, NULL);
      pthread_cond_init(&amp;cond, NULL);
      pthread_rwlock_init(&amp;rwlock, &amp;attr);
      counter = 0;
  
      //create threads
      pthread_t threadArray[workers];
      int threadOrder[workers];
      for (int i = 0; i &lt; workers; i++){
          threadOrder[i] = i;
          if (pthread_create(&amp;threadArray[i], NULL,
                      worker, &amp;threadOrder[i]) != 0){
              perror("Cannot create thread");
              exit(1);
          }
      }
  
      while(listLength != 0) {
          //wait for signal and lock the list
          pthread_mutex_lock(&amp;mutex);
          while (pthread_cond_wait(&amp;cond, &amp;mutex) != 0);
          pthread_rwlock_wrlock(&amp;rwlock);
          printf("In write lock\n");
  
          pthread_mutex_unlock(&amp;mutex);
          pthread_rwlock_unlock(&amp;rwlock);
          printf("release wrlock\n");
      }
  
      //join the threads
      for (int i = 0; i &lt; workers; i++){
          if (pthread_join(threadArray[i], NULL) !=0){
              perror("Cannot join thread");
             exit(1);
          }
      }
  
      //release resources
      pthread_mutex_destroy(&amp;mutex);
      pthread_cond_destroy(&amp;cond);
      pthread_rwlock_destroy(&amp;rwlock);
  
      return 0;
  }
  </code></pre>