Back to index

glibc  2.9
Functions
pthread_rwlock_wrlock.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_wrlock (pthread_rwlock_t *rwlock)

Function Documentation

int __pthread_rwlock_wrlock ( pthread_rwlock_t *  rwlock)

Definition at line 29 of file pthread_rwlock_wrlock.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 and no reader.  */
      if (rwlock->__data.__writer == 0 && rwlock->__data.__nr_readers == 0)
       {
         /* Mark self as writer.  */
         rwlock->__data.__writer = THREAD_GETMEM (THREAD_SELF, tid);
         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 writer.  */
      if (++rwlock->__data.__nr_writers_queued == 0)
       {
         /* Overflow on number of queued writers.  */
         --rwlock->__data.__nr_writers_queued;
         result = EAGAIN;
         break;
       }

      int waitval = rwlock->__data.__writer_wakeup;

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

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

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

      /* To start over again, remove the thread from the writer list.  */
      --rwlock->__data.__nr_writers_queued;
    }

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

  return result;
}