diff options
Diffstat (limited to 'winsup/cygwin/thread.cc')
-rw-r--r-- | winsup/cygwin/thread.cc | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index ecf928784..8bb68703e 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -1227,9 +1227,13 @@ pthread_rwlock::rdlock () mtx.lock (); - if (lookup_reader (self)) + reader = lookup_reader (self); + if (reader) { - result = EDEADLK; + if (reader->n < ULONG_MAX) + ++reader->n; + else + errno = EAGAIN; goto DONE; } @@ -1252,6 +1256,7 @@ pthread_rwlock::rdlock () } reader->thread = self; + reader->n = 1; add_reader (reader); DONE: @@ -1272,10 +1277,15 @@ pthread_rwlock::tryrdlock () result = EBUSY; else { - struct RWLOCK_READER *reader = new struct RWLOCK_READER; - if (reader) + struct RWLOCK_READER *reader; + + reader = lookup_reader (self); + if (reader && reader->n < ULONG_MAX) + ++reader->n; + else if ((reader = new struct RWLOCK_READER)) { reader->thread = self; + reader->n = 1; add_reader (reader); } else @@ -1365,6 +1375,8 @@ pthread_rwlock::unlock () result = EPERM; goto DONE; } + if (--reader->n > 0) + goto DONE; remove_reader (reader); delete reader; |