Date: Thu, 25 Jan 2001 09:48:08 -0800 (PST) From: earl_chew@agilent.com To: freebsd-gnats-submit@FreeBSD.org Subject: misc/24641: pthread_rwlock_rdlock can deadlock Message-ID: <200101251748.f0PHm8B52012@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 24641 >Category: misc >Synopsis: pthread_rwlock_rdlock can deadlock >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Jan 25 09:50:00 PST 2001 >Closed-Date: >Last-Modified: >Originator: Earl Chew >Release: 3.3-RELEASE >Organization: Agilent Technologies >Environment: FreeBSD qar1 3.3-RELEASE FreeBSD 3.3-RELEASE #0: Tue Oct 17 16:21:01 EDT 2000 >Description: The man page for pthread_rwlock_rdlock() says: A thread may hold multiple concurrent read locks. If so, pthread_rwlock_unlock() must be called once for each lock obtained. I tried this out after reading Bill Lewis' article on Usenet: http://x64.deja.com/[ST_rn=ps]/getdoc.xp?AN=573590892&search=thread&CONTEXT=980444523.1181483044&HIT_CONTEXT=980444500.1181483040&HIT_NUM=11&hitnum=3 Bill wrote: Consider: T1 gets a read lock. T2 wants a write lock & blocks, waiting for T1. Now T1 wants a read lock again. Because writers have priority, T1 will now block, waiting for T2. My test program prints the following, then gets stuck: > ./a.out Attempt to acquire read lock first Acquired read lock first Attempt to acquire write lock Attempt to acquire read lock second Examining the source code (uthread_rwlock.c,v 1.5) it is pretty clear why this deadlock occurs (as Bill Lewis predicts). >How-To-Repeat: #include <pthread.h> #include <stdio.h> #include <unistd.h> #include <assert.h> static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; static volatile int wrStarted; void * wrfunc(void *) { printf("Attempt to acquire write lock\n"); assert(pthread_rwlock_wrlock(&rwlock1) == 0); printf("Acquired write lock\n"); assert(pthread_rwlock_unlock(&rwlock1) == 0); return 0; } static volatile int rdStarted; void * rdfunc(void *) { printf("Attempt to acquire read lock first\n"); assert(pthread_rwlock_rdlock(&rwlock1) == 0); printf("Acquired read lock first\n"); rdStarted = 1; while (wrStarted == 0) sleep(1); printf("Attempt to acquire read lock second\n"); assert(pthread_rwlock_rdlock(&rwlock1) == 0); printf("Acquired read lock second\n"); assert(pthread_rwlock_unlock(&rwlock1) == 0); assert(pthread_rwlock_unlock(&rwlock1) == 0); return 0; } int main(int, char**) { pthread_t wrt; pthread_t rdt; pthread_attr_t a; assert(pthread_rwlock_init(&rwlock1, 0) == 0); assert(pthread_attr_init(&a) == 0); assert(pthread_create(&rdt, &a, rdfunc, NULL) == 0); while (rdStarted == 0) sleep(1); assert(pthread_create(&wrt, &a, wrfunc, NULL) == 0); assert(pthread_join(wrt, 0) == 0); assert(pthread_join(rdt, 0) == 0); assert(pthread_rwlock_destroy(&rwlock1) == 0); assert(pthread_detach(wrt) == 0); assert(pthread_detach(rdt) == 0); return 0; } >Fix: >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200101251748.f0PHm8B52012>
