Back to index

glibc  2.9
Functions
pthread_rwlock_rdlock.c File Reference
#include <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <pthread.h>
#include <pthreadP.h>

Go to the source code of this file.

Functions

int __pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)

Function Documentation

int __pthread_rwlock_rdlock ( pthread_rwlock_t *  rwlock)

Definition at line 29 of file pthread_rwlock_rdlock.c.

{
  int result = 0;

  /* Make sure we are along.  */
  lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);

  while (1)
    {
      /* Get the rwlock if there is no writer...  */
      if (rwlock->__data.__writer == 0
         /* ...and if either no writer is waiting or we prefer readers.  */
         && (!rwlock->__data.__nr_writers_queued
             || PTHREAD_RWLOCK_PREFER_READER_P (rwlock)))
       {
         /* Increment the reader counter.  Avoid overflow.  */
         if (__builtin_expect (++rwlock->__data.__nr_readers == 0, 0))
           {
             /* Overflow on number of readers.    */
             --rwlock->__data.__nr_readers;
             result = EAGAIN;
           }

         break;
       }

      /* Make sure we are not holding the rwlock as a writer.  This is
        a deadlock situation we recognize and report.  */
      if (__builtin_expect (rwlock->__data.__writer
                         == THREAD_GETMEM (THREAD_SELF, tid), 0))
       {
         result = EDEADLK;
         break;
       }

      /* Remember that we are a reader.  */
      if (__builtin_expect (++rwlock->__data.__nr_readers_queued == 0, 0))
       {
         /* Overflow on number of queued readers.  */
         --rwlock->__data.__nr_readers_queued;
         result = EAGAIN;
         break;
       }

      int waitval = rwlock->__data.__readers_wakeup;

      /* Free the lock.  */
      lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);

      /* Wait for the writer to finish.  */
      lll_futex_wait (&rwlock->__data.__readers_wakeup, waitval,
                    rwlock->__data.__shared);

      /* Get the lock.  */
      lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);

      --rwlock->__data.__nr_readers_queued;
    }

  /* We are done, free the lock.  */
  lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);

  return result;
}