src/lib/rwlock.c
int rwl_writelock_p(brwlock_t *rwl, const char *file, int line)
{
   int stat;

   if (rwl->valid != RWLOCK_VALID) {
      return EINVAL;
   }
   if ((stat = pthread_mutex_lock(&rwl->mutex)) != 0) {
      return stat;
   }
   if (rwl->w_active && pthread_equal(rwl->writer_id, pthread_self())) {
      rwl->w_active++;
      pthread_mutex_unlock(&rwl->mutex);
      return 0;
   }
   lmgr_pre_lock(rwl, rwl->priority, file, line);
   if (rwl->w_active || rwl->r_active > 0) {
      rwl->w_wait++;                  /* indicate that we are waiting */
      pthread_cleanup_push(rwl_write_release, (void *)rwl);
      while (rwl->w_active || rwl->r_active > 0) {
         if ((stat = pthread_cond_wait(&rwl->write, &rwl->mutex)) != 0) {
            lmgr_do_unlock(rwl);
            break;                    /* error, bail out */
         }
      }
      pthread_cleanup_pop(0);
      rwl->w_wait--;                  /* we are no longer waiting */
   }
   if (stat == 0) {
      rwl->w_active++;                /* we are running */
      rwl->writer_id = pthread_self(); /* save writer thread's id */
      lmgr_post_lock();
   }
   pthread_mutex_unlock(&rwl->mutex);
   return stat;
}
/*
 * Lock for write access, wait until locked (or error).
 *   Multiple nested write locking is permitted.
 */
Lock for write access, wait until locked (or error).
Multiple nested write locking is permitted.
Lock for write access wait until locked ( or error ) . Multiple nested write locking is permitted .
int rwl_writelock_p(brwlock_t *rwl, const char *file, int line)
{
   int stat;
   if (rwl->valid != RWLOCK_VALID) {
      return EINVAL;
   }
   if ((stat = pthread_mutex_lock(&rwl->mutex)) != 0) {
      return stat;
   }
   if (rwl->w_active && pthread_equal(rwl->writer_id, pthread_self())) {
      rwl->w_active++;
      pthread_mutex_unlock(&rwl->mutex);
      return 0;
   }
   lmgr_pre_lock(rwl, rwl->priority, file, line);
   if (rwl->w_active || rwl->r_active > 0) {
      rwl->w_wait++;                  
      pthread_cleanup_push(rwl_write_release, (void *)rwl);
      while (rwl->w_active || rwl->r_active > 0) {
         if ((stat = pthread_cond_wait(&rwl->write, &rwl->mutex)) != 0) {
            lmgr_do_unlock(rwl);
            break;                    
         }
      }
      pthread_cleanup_pop(0);
      rwl->w_wait--;                  
   }
   if (stat == 0) {
      rwl->w_active++;                
      rwl->writer_id = pthread_self(); 
      lmgr_post_lock();
   }
   pthread_mutex_unlock(&rwl->mutex);
   return stat;
}
int rwl_writelock_p ( brwlock_t * rwl , const char * file , int line ) { int stat ; if ( rwl -> valid != RWLOCK_VALID ) { return EINVAL ; } if ( ( stat = pthread_mutex_lock ( & rwl -> mutex ) ) != 0 ) { return stat ; } if ( rwl -> w_active && pthread_equal ( rwl -> writer_id , pthread_self ( ) ) ) { rwl -> w_active ++ ; pthread_mutex_unlock ( & rwl -> mutex ) ; return 0 ; } lmgr_pre_lock ( rwl , rwl -> priority , file , line ) ; if ( rwl -> w_active || rwl -> r_active > 0 ) { rwl -> w_wait ++ ; pthread_cleanup_push ( rwl_write_release , ( void * ) rwl ) ; while ( rwl -> w_active || rwl -> r_active > 0 ) { if ( ( stat = pthread_cond_wait ( & rwl -> write , & rwl -> mutex ) ) != 0 ) { lmgr_do_unlock ( rwl ) ; break ; } } pthread_cleanup_pop ( 0 ) ; rwl -> w_wait -- ; } if ( stat == 0 ) { rwl -> w_active ++ ; rwl -> writer_id = pthread_self ( ) ; lmgr_post_lock ( ) ; } pthread_mutex_unlock ( & rwl -> mutex ) ; return stat ; }
Lock for write access, wait until locked (or error).
Lock for write access wait until locked ( or error ) .
/* indicate that we are waiting */ /* error, bail out */ /* we are no longer waiting */ /* we are running */ /* save writer thread's id */