* 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.
This commit is contained in:
Corinna Vinschen 2009-01-20 12:40:31 +00:00
parent 3787b37ef2
commit f8190b5705
3 changed files with 26 additions and 4 deletions

View File

@ -1,3 +1,12 @@
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> 2009-01-20 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (WSAIoctl): Reintroduce. * autoload.cc (WSAIoctl): Reintroduce.

View File

@ -1227,9 +1227,13 @@ pthread_rwlock::rdlock ()
mtx.lock (); 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; goto DONE;
} }
@ -1252,6 +1256,7 @@ pthread_rwlock::rdlock ()
} }
reader->thread = self; reader->thread = self;
reader->n = 1;
add_reader (reader); add_reader (reader);
DONE: DONE:
@ -1272,10 +1277,15 @@ pthread_rwlock::tryrdlock ()
result = EBUSY; result = EBUSY;
else else
{ {
struct RWLOCK_READER *reader = new struct RWLOCK_READER; struct RWLOCK_READER *reader;
if (reader)
reader = lookup_reader (self);
if (reader && reader->n < ULONG_MAX)
++reader->n;
else if ((reader = new struct RWLOCK_READER))
{ {
reader->thread = self; reader->thread = self;
reader->n = 1;
add_reader (reader); add_reader (reader);
} }
else else
@ -1365,6 +1375,8 @@ pthread_rwlock::unlock ()
result = EPERM; result = EPERM;
goto DONE; goto DONE;
} }
if (--reader->n > 0)
goto DONE;
remove_reader (reader); remove_reader (reader);
delete reader; delete reader;

View File

@ -556,6 +556,7 @@ public:
{ {
struct RWLOCK_READER *next; struct RWLOCK_READER *next;
pthread_t thread; pthread_t thread;
unsigned long n;
} *readers; } *readers;
fast_mutex readers_mx; fast_mutex readers_mx;