I have following sample code (see code below) that does by thread:
A: rd-lock
B: wr-lock (waiting)
A: rd-lock (recursive)
A: rd-unlock (recursive)
A: rd-unlock
B: wr-locked (wake after wait)
B: wr-unlock.
Basically read-lock is recursive. It it required by POSIX standards (requires read locks to be recursive, but not specified for write locks). This works on Linux, FreeBSD, Solaris, however it does not work on Darwin/Mac OS X.
The sample below gives following output on Linux:
read locking
read locked
write locking
read locking 2
read locked 2
read unlocked 2
read unlocked
write locked
write unlocked 2
While on Darwin it prints:
read locking
read locked
write locking
read locking 2
And deadlocks here (does not continue), basically it does not respect recursive read lock.
Is there anything that possible to do (flag, defined, link with a special library version) that it would work as expected?
Sample code
#include <pthread.h>
#include <stdio.h>
pthread_rwlock_t lock;
void *thread_r(void *p)
{
printf("read locking\n");
pthread_rwlock_rdlock(&lock);
printf("read locked\n");
usleep(500*1000);
printf("read locking 2\n");
pthread_rwlock_rdlock(&lock);
printf("read locked 2\n");
usleep(500*1000);
pthread_rwlock_unlock(&lock);
printf("read unlocked 2\n");
usleep(500*1000);
pthread_rwlock_unlock(&lock);
printf("read unlocked\n");
}
void *thread_w(void *p)
{
usleep(250*1000);
printf("write locking\n");
pthread_rwlock_wrlock(&lock);
printf("write locked\n");
pthread_rwlock_unlock(&lock);
printf("write unlocked 2\n");
}
int main()
{
pthread_t a,b;
pthread_rwlock_init(&lock,NULL);
pthread_create(&a,NULL,thread_r,0);
pthread_create(&b,NULL,thread_w,0);
pthread_join(a,NULL);
pthread_join(b,NULL);
return 0;
}