diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2009-01-20 12:40:31 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2009-01-20 12:40:31 +0000 |
commit | f8190b57056cc10ec0da28b0685ec6fe59b1e4cb (patch) | |
tree | 5a4289b8199ac2262c411f0f08f3941f37ca5feb /winsup | |
parent | 3787b37ef2c8a86a1c67ccef6dde3df568ed5ae9 (diff) | |
download | cygnal-f8190b57056cc10ec0da28b0685ec6fe59b1e4cb.tar.gz cygnal-f8190b57056cc10ec0da28b0685ec6fe59b1e4cb.tar.bz2 cygnal-f8190b57056cc10ec0da28b0685ec6fe59b1e4cb.zip |
* thread.h (struct pthread_rwlock::RWLOCK_READER): Add counter n.
* thread.cc (pthread_rwlock::rdlock): If a thread already owns a
read lock, just count the number of locks for it, per SUSv4.
(pthread_rwlock::tryrdlock): Ditto.
(pthread_rwlock::unlock): If a thread has more than one concurrent
read locks, just count down.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 9 | ||||
-rw-r--r-- | winsup/cygwin/thread.cc | 20 | ||||
-rw-r--r-- | winsup/cygwin/thread.h | 1 |
3 files changed, 26 insertions, 4 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index efbaffb9f..022a25103 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,14 @@ 2009-01-20 Corinna Vinschen <corinna@vinschen.de> + * thread.h (struct pthread_rwlock::RWLOCK_READER): Add counter n. + * thread.cc (pthread_rwlock::rdlock): If a thread already owns a + read lock, just count the number of locks for it, per SUSv4. + (pthread_rwlock::tryrdlock): Ditto. + (pthread_rwlock::unlock): If a thread has more than one concurrent + read locks, just count down. + +2009-01-20 Corinna Vinschen <corinna@vinschen.de> + * autoload.cc (WSAIoctl): Reintroduce. (WSASendMsg): Define. * fhandler.h (class fhandler_socket): Change definition of recv_internal 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; diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index db94fd2c2..c2a1be8f1 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -556,6 +556,7 @@ public: { struct RWLOCK_READER *next; pthread_t thread; + unsigned long n; } *readers; fast_mutex readers_mx; |