Redesigned how cancellation unblocks a thread from internal
[kopensolaris-gnu/glibc.git] / linuxthreads / rwlock.c
index 99209f7..1d78b78 100644 (file)
 #include <pthread.h>
 #include "internals.h"
 #include "queue.h"
-#include "restart.h"
 #include "spinlock.h"
+#include "restart.h"
 
 int
 pthread_rwlock_init (pthread_rwlock_t *rwlock,
                     const pthread_rwlockattr_t *attr)
 {
-  __pthread_init_lock(&rwlock->rw_lock);
-  rwlock->rw_readers = 0;
-  rwlock->rw_writer = NULL;
-  rwlock->rw_read_waiting = NULL;
-  rwlock->rw_write_waiting = NULL;
+  __pthread_init_lock(&rwlock->__rw_lock);
+  rwlock->__rw_readers = 0;
+  rwlock->__rw_writer = NULL;
+  rwlock->__rw_read_waiting = NULL;
+  rwlock->__rw_write_waiting = NULL;
 
   if (attr == NULL)
     {
-      rwlock->rw_kind = PTHREAD_RWLOCK_DEFAULT_NP;
-      rwlock->rw_pshared = PTHREAD_PROCESS_PRIVATE;
+      rwlock->__rw_kind = PTHREAD_RWLOCK_DEFAULT_NP;
+      rwlock->__rw_pshared = PTHREAD_PROCESS_PRIVATE;
     }
   else
     {
-      rwlock->rw_kind = attr->lockkind;
-      rwlock->rw_pshared = attr->pshared;
+      rwlock->__rw_kind = attr->__lockkind;
+      rwlock->__rw_pshared = attr->__pshared;
     }
 
   return 0;
@@ -57,10 +57,10 @@ pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
   int readers;
   _pthread_descr writer;
 
-  __pthread_lock (&rwlock->rw_lock);
-  readers = rwlock->rw_readers;
-  writer = rwlock->rw_writer;
-  __pthread_unlock (&rwlock->rw_lock);
+  __pthread_lock (&rwlock->__rw_lock, NULL);
+  readers = rwlock->__rw_readers;
+  writer = rwlock->__rw_writer;
+  __pthread_unlock (&rwlock->__rw_lock);
 
   if (readers > 0 || writer != NULL)
     return EBUSY;
@@ -72,26 +72,27 @@ pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
 int
 pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
 {
-  pthread_descr self;
+  pthread_descr self = NULL;
 
   while (1)
     {
-      __pthread_lock (&rwlock->rw_lock);
-      if (rwlock->rw_writer == NULL
-         || (rwlock->rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
-             && rwlock->rw_readers != 0))
+      __pthread_lock (&rwlock->__rw_lock, self);
+      if (rwlock->__rw_writer == NULL
+         || (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
+             && rwlock->__rw_readers != 0))
        /* We can add a reader lock.  */
        break;
 
       /* Suspend ourselves, then try again */
-      self = thread_self ();
-      enqueue (&rwlock->rw_read_waiting, self);
-      __pthread_unlock (&rwlock->rw_lock);
+      if (self == NULL)
+       self = thread_self ();
+      enqueue (&rwlock->__rw_read_waiting, self);
+      __pthread_unlock (&rwlock->__rw_lock);
       suspend (self); /* This is not a cancellation point */
     }
 
-  ++rwlock->rw_readers;
-  __pthread_unlock (&rwlock->rw_lock);
+  ++rwlock->__rw_readers;
+  __pthread_unlock (&rwlock->__rw_lock);
 
   return 0;
 }
@@ -102,15 +103,15 @@ pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
 {
   int result = EBUSY;
 
-  __pthread_lock (&rwlock->rw_lock);
-  if (rwlock->rw_writer == NULL
-      || (rwlock->rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
-         && rwlock->rw_readers != 0))
+  __pthread_lock (&rwlock->__rw_lock, NULL);
+  if (rwlock->__rw_writer == NULL
+      || (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
+         && rwlock->__rw_readers != 0))
     {
-      ++rwlock->rw_readers;
+      ++rwlock->__rw_readers;
       result = 0;
     }
-  __pthread_unlock (&rwlock->rw_lock);
+  __pthread_unlock (&rwlock->__rw_lock);
 
   return result;
 }
@@ -123,17 +124,17 @@ pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
 
   while(1)
     {
-      __pthread_lock (&rwlock->rw_lock);
-      if (rwlock->rw_readers == 0 && rwlock->rw_writer == NULL)
+      __pthread_lock (&rwlock->__rw_lock, self);
+      if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL)
        {
-         rwlock->rw_writer = self;
-         __pthread_unlock (&rwlock->rw_lock);
+         rwlock->__rw_writer = self;
+         __pthread_unlock (&rwlock->__rw_lock);
          return 0;
        }
 
       /* Suspend ourselves, then try again */
-      enqueue (&rwlock->rw_write_waiting, self);
-      __pthread_unlock (&rwlock->rw_lock);
+      enqueue (&rwlock->__rw_write_waiting, self);
+      __pthread_unlock (&rwlock->__rw_lock);
       suspend (self); /* This is not a cancellation point */
     }
 }
@@ -144,13 +145,13 @@ pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
 {
   int result = EBUSY;
 
-  __pthread_lock (&rwlock->rw_lock);
-  if (rwlock->rw_readers == 0 && rwlock->rw_writer == NULL)
+  __pthread_lock (&rwlock->__rw_lock, NULL);
+  if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL)
     {
-      rwlock->rw_writer = thread_self ();
+      rwlock->__rw_writer = thread_self ();
       result = 0;
     }
-  __pthread_unlock (&rwlock->rw_lock);
+  __pthread_unlock (&rwlock->__rw_lock);
 
   return result;
 }
@@ -162,51 +163,51 @@ pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
   pthread_descr torestart;
   pthread_descr th;
 
-  __pthread_lock (&rwlock->rw_lock);
-  if (rwlock->rw_writer != NULL)
+  __pthread_lock (&rwlock->__rw_lock, NULL);
+  if (rwlock->__rw_writer != NULL)
     {
       /* Unlocking a write lock.  */
-      if (rwlock->rw_writer != thread_self ())
+      if (rwlock->__rw_writer != thread_self ())
        {
-         __pthread_unlock (&rwlock->rw_lock);
+         __pthread_unlock (&rwlock->__rw_lock);
          return EPERM;
        }
-      rwlock->rw_writer = NULL;
+      rwlock->__rw_writer = NULL;
 
-      if (rwlock->rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
-         || (th = dequeue (&rwlock->rw_write_waiting)) == NULL)
+      if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP
+         || (th = dequeue (&rwlock->__rw_write_waiting)) == NULL)
        {
          /* Restart all waiting readers.  */
-         torestart = rwlock->rw_read_waiting;
-         rwlock->rw_read_waiting = NULL;
-         __pthread_unlock (&rwlock->rw_lock);
+         torestart = rwlock->__rw_read_waiting;
+         rwlock->__rw_read_waiting = NULL;
+         __pthread_unlock (&rwlock->__rw_lock);
          while ((th = dequeue (&torestart)) != NULL)
            restart (th);
        }
       else
        {
          /* Restart one waiting writer.  */
-         __pthread_unlock (&rwlock->rw_lock);
+         __pthread_unlock (&rwlock->__rw_lock);
          restart (th);
        }
     }
   else
     {
       /* Unlocking a read lock.  */
-      if (rwlock->rw_readers == 0)
+      if (rwlock->__rw_readers == 0)
        {
-         __pthread_unlock (&rwlock->rw_lock);
+         __pthread_unlock (&rwlock->__rw_lock);
          return EPERM;
        }
 
-      --rwlock->rw_readers;
-      if (rwlock->rw_readers == 0)
+      --rwlock->__rw_readers;
+      if (rwlock->__rw_readers == 0)
        /* Restart one waiting writer, if any.  */
-       th = dequeue (&rwlock->rw_write_waiting);
+       th = dequeue (&rwlock->__rw_write_waiting);
       else
        th = NULL;
 
-      __pthread_unlock (&rwlock->rw_lock);
+      __pthread_unlock (&rwlock->__rw_lock);
       if (th != NULL)
        restart (th);
     }
@@ -219,8 +220,8 @@ pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
 int
 pthread_rwlockattr_init (pthread_rwlockattr_t *attr)
 {
-  attr->lockkind = 0;
-  attr->pshared = 0;
+  attr->__lockkind = 0;
+  attr->__pshared = 0;
 
   return 0;
 }
@@ -236,7 +237,7 @@ pthread_rwlockattr_destroy (pthread_rwlockattr_t *attr)
 int
 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared)
 {
-  *pshared = attr->pshared;
+  *pshared = attr->__pshared;
   return 0;
 }
 
@@ -247,7 +248,7 @@ pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared)
   if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED)
     return EINVAL;
 
-  attr->pshared = pshared;
+  attr->__pshared = pshared;
 
   return 0;
 }
@@ -256,7 +257,7 @@ pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared)
 int
 pthread_rwlockattr_getkind_np (const pthread_rwlockattr_t *attr, int *pref)
 {
-  *pref = attr->lockkind;
+  *pref = attr->__lockkind;
   return 0;
 }
 
@@ -269,7 +270,7 @@ pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, int pref)
       && pref != PTHREAD_RWLOCK_DEFAULT_NP)
     return EINVAL;
 
-  attr->lockkind = pref;
+  attr->__lockkind = pref;
 
   return 0;
 }