diff -u3 old/pth.h.in new/pth.h.in
--- old/pth.h.in	Sat Mar  2 19:34:05 2002
+++ new/pth.h.in	Sat Mar  2 19:41:00 2002
@@ -234,7 +234,7 @@
 #define PTH_MUTEX_INIT               { {NULL, NULL}, PTH_MUTEX_INITIALIZED, NULL, 0 }
 
    /* read-write lock values */
-enum { PTH_RWLOCK_RD, PTH_RWLOCK_RW };
+enum { PTH_RWLOCK_UL, PTH_RWLOCK_RD, PTH_RWLOCK_RW }; /* xgl */
 #define PTH_RWLOCK_INITIALIZED       _BIT(0)
 #define PTH_RWLOCK_INIT              { PTH_RWLOCK_INITIALIZED, PTH_RWLOCK_RD, 0, \
                                        PTH_MUTEX_INIT, PTH_MUTEX_INIT }
@@ -276,21 +276,21 @@
     unsigned long  mx_count;
 };
 
+    /* the condition variable structure */
+typedef struct pth_cond_st pth_cond_t;
+struct pth_cond_st { /* not hidden to avoid destructor */
+    unsigned long cn_state;
+    unsigned int  cn_waiters;
+};
+
     /* the read-write lock structure */
 typedef struct pth_rwlock_st pth_rwlock_t;
 struct pth_rwlock_st { /* not hidden to avoid destructor */
     int            rw_state;
     unsigned int   rw_mode;
     unsigned long  rw_readers;
-    pth_mutex_t    rw_mutex_rd;
+    pth_cond_t     rw_cond_rw;   /* xgl */
     pth_mutex_t    rw_mutex_rw;
-};
-
-    /* the condition variable structure */
-typedef struct pth_cond_st pth_cond_t;
-struct pth_cond_st { /* not hidden to avoid destructor */
-    unsigned long cn_state;
-    unsigned int  cn_waiters;
 };
 
     /* the barrier variable structure */
diff -u3 old/pth_sync.c new/pth_sync.c
--- old/pth_sync.c	Sat Mar  2 18:18:35 2002
+++ new/pth_sync.c	Sat Mar  2 19:56:00 2002
@@ -152,7 +152,7 @@
         return_errno(FALSE, EINVAL);
     rwlock->rw_state = PTH_RWLOCK_INITIALIZED;
     rwlock->rw_readers = 0;
-    pth_mutex_init(&(rwlock->rw_mutex_rd));
+    pth_cond_init(&(rwlock->rw_cond_rw));
     pth_mutex_init(&(rwlock->rw_mutex_rw));
     return TRUE;
 }
@@ -167,25 +167,29 @@
 
     /* acquire lock */
     if (op == PTH_RWLOCK_RW) {
-        /* read-write lock is simple */
+        /* xgl: read-write lock is not so simple */
         if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), tryonly, ev_extra))
             return FALSE;
+        if (rwlock->rw_readers || (PTH_RWLOCK_RW == rwlock->rw_mode)) {
+            if (!pth_cond_await(&(rwlock->rw_cond_rw), &(rwlock->rw_mutex_rw), NULL))
+                return FALSE;
+        }
         rwlock->rw_mode = PTH_RWLOCK_RW;
+        if (!pth_mutex_release(&(rwlock->rw_mutex_rw)))
+            return FALSE;
     }
     else {
-        /* read-only lock is more complicated to get right */
-        if (!pth_mutex_acquire(&(rwlock->rw_mutex_rd), tryonly, ev_extra))
+        /* xgl: read-only lock is not much more complicated to get right */
+        if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), tryonly, ev_extra))
             return FALSE;
-        rwlock->rw_readers++;
-        if (rwlock->rw_readers == 1) {
-            if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), tryonly, ev_extra)) {
-                rwlock->rw_readers--;
-                errno_shield { pth_mutex_release(&(rwlock->rw_mutex_rd)); }
+        if (PTH_RWLOCK_RW == rwlock->rw_mode) {
+            if (!pth_cond_await(&(rwlock->rw_cond_rw), &(rwlock->rw_mutex_rw), NULL))
                 return FALSE;
-            }
         }
+        rwlock->rw_readers++;
         rwlock->rw_mode = PTH_RWLOCK_RD;
-        pth_mutex_release(&(rwlock->rw_mutex_rd));
+        if (!pth_mutex_release(&(rwlock->rw_mutex_rw)))
+            return FALSE;
     }
     return TRUE;
 }
@@ -200,24 +204,35 @@
 
     /* release lock */
     if (rwlock->rw_mode == PTH_RWLOCK_RW) {
-        /* read-write unlock is simple */
+        /* xgl: read-write unlock is not so simple */
+        if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), FALSE, NULL))
+            return FALSE;
+        rwlock->rw_mode = PTH_RWLOCK_UL;
         if (!pth_mutex_release(&(rwlock->rw_mutex_rw)))
             return FALSE;
+        if (!pth_cond_notify(&(rwlock->rw_cond_rw), TRUE))
+            return FALSE;
     }
     else {
-        /* read-only unlock is more complicated to get right */
-        if (!pth_mutex_acquire(&(rwlock->rw_mutex_rd), FALSE, NULL))
+        /* xgl: read-only unlock is not much more complicated to get right */
+        if (!pth_mutex_acquire(&(rwlock->rw_mutex_rw), FALSE, NULL))
             return FALSE;
         rwlock->rw_readers--;
         if (rwlock->rw_readers == 0) {
+            rwlock->rw_mode = PTH_RWLOCK_UL;
             if (!pth_mutex_release(&(rwlock->rw_mutex_rw))) {
                 rwlock->rw_readers++;
-                errno_shield { pth_mutex_release(&(rwlock->rw_mutex_rd)); }
+                return FALSE;
+            }
+            if (!pth_cond_notify(&(rwlock->rw_cond_rw), TRUE)) {
+                rwlock->rw_readers++;
                 return FALSE;
             }
         }
-        rwlock->rw_mode = PTH_RWLOCK_RD;
-        pth_mutex_release(&(rwlock->rw_mutex_rd));
+        else {
+            if (!pth_mutex_release(&(rwlock->rw_mutex_rw)))
+                return FALSE;
+        }
     }
     return TRUE;
 }
