* 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>
+
+ * 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.
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;
}
}
reader->thread = self;
+ reader->n = 1;
add_reader (reader);
DONE:
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
result = EPERM;
goto DONE;
}
+ if (--reader->n > 0)
+ goto DONE;
remove_reader (reader);
delete reader;
{
struct RWLOCK_READER *next;
pthread_t thread;
+ unsigned long n;
} *readers;
fast_mutex readers_mx;