This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug nptl/14652] New: Cancelling a pthread_cond_wait with PRIO_INHERIT mutex causes a deadlock
- From: "siddhesh at redhat dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sources dot redhat dot com
- Date: Mon, 01 Oct 2012 18:28:01 +0000
- Subject: [Bug nptl/14652] New: Cancelling a pthread_cond_wait with PRIO_INHERIT mutex causes a deadlock
- Auto-submitted: auto-generated
http://sourceware.org/bugzilla/show_bug.cgi?id=14652
Bug #: 14652
Summary: Cancelling a pthread_cond_wait with PRIO_INHERIT mutex
causes a deadlock
Product: glibc
Version: unspecified
Status: NEW
Severity: normal
Priority: P2
Component: nptl
AssignedTo: unassigned@sourceware.org
ReportedBy: siddhesh@redhat.com
CC: drepper.fsp@gmail.com
Classification: Unclassified
This is different from bug 14477, which is a deadlock due to an incorrect
exception table. This problem is sometimes seen when a program with multiple
waiters and signallers are cancelled. One of the waiters could get cancelled
at a point after it has returned successfully from a futex_wait and before it
disables async cancellation. Since a wait with PRIO_INHERIT mutex uses the
FUTEX_WAIT_REQUEUE_PI futex operation, the futex syscall returns with the mutex
locked. The cleanup handler subsequently tries to lock this already locked
mutex, resulting in a deadlock.
The following program demonstrates this on i386 as well as x86_64:
#include <pthread.h>
#include <stdio.h>
#define NUM 5
#define ITERS 100000
pthread_mutex_t mutex;
pthread_cond_t cond;
void cleanup (void *u)
{
pthread_mutex_unlock (&mutex);
}
void *
signaller (void *u)
{
int i;
for (i = 0; i < ITERS / NUM; i++)
{
pthread_mutex_lock (&mutex);
pthread_cond_signal (&cond);
puts ("signalled");
fflush (stdout);
pthread_mutex_unlock (&mutex);
}
}
void *
waiter (void *u)
{
int i;
for (i = 0; i < ITERS / NUM; i++)
{
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 20;
pthread_mutex_lock (&mutex);
pthread_cleanup_push (cleanup, NULL);
puts ("waiting...");
pthread_cond_timedwait (&cond, &mutex, &ts);
puts ("waited");
fflush (stdout);
pthread_mutex_unlock (&mutex);
pthread_cleanup_pop (0);
}
}
int
main (void)
{
pthread_t w[NUM];
pthread_t s;
pthread_mutexattr_t attr;
int i;
for (i = 0; i < ITERS; i++)
{
pthread_mutexattr_init (&attr);
pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_INHERIT);
pthread_cond_init (&cond, NULL);
pthread_mutex_init (&mutex, &attr);
for (i = 0; i < NUM; i++)
pthread_create (&w[i], NULL, waiter, NULL);
pthread_create (&s, NULL, signaller, NULL);
for (i = 0; i < NUM; i++)
{
pthread_cancel (w[i]);
pthread_join (w[i], NULL);
}
pthread_cancel (s);
pthread_join (s, NULL);
}
return 0;
}
The program hangs after some iterations. I have a patch in the works that
should fix this.
--
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.