summaryrefslogtreecommitdiffstats
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2009-01-20 12:40:31 +0000
committerCorinna Vinschen <corinna@vinschen.de>2009-01-20 12:40:31 +0000
commitf8190b57056cc10ec0da28b0685ec6fe59b1e4cb (patch)
tree5a4289b8199ac2262c411f0f08f3941f37ca5feb /winsup
parent3787b37ef2c8a86a1c67ccef6dde3df568ed5ae9 (diff)
downloadcygnal-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/ChangeLog9
-rw-r--r--winsup/cygwin/thread.cc20
-rw-r--r--winsup/cygwin/thread.h1
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;