Description of problem: Create 2 threads that wait on the same condition. Then try to call pthread_cancel() to kill them. The first thread is terminated correctly; the second doesn't. In the attached test code, t2 never gets terminated and pthread_join(t2, NULL) never returns. Version-Release number of selected component (if applicable): RHEL 3 ------ kernel: kernel-smp-2.4.21-27.0.2.EL gcc: gcc-3.2.3-49 glibc: glibc-2.3.2-95.30 RHEL 4 ------ kernel: kernel-2.6.9-5.0.3.EL gcc: gcc-3.4.3-9.EL4 glibc: glibc-2.3.4-2 How reproducible: Always Steps to Reproduce: Compile the test code with: 1. gcc pthr_cancel_test.c -pthread 2. ./a.out Actual results: pthread_join(t2) never returns Expected results: pthread_join(t2) should return Additional info:
Created attachment 113005 [details] C code to reproduce the problem
BTW, if t1 and t2 waits on 2 different conditions, pthread_cancel() works correctly.
That's the correct behaviour. See http://www.opengroup.org/onlinepubs/009695399/functions/pthread_cond_timedwait.html A side effect of acting on a cancellation request while a thread is blocked on a condition variable is to re-acquire the mutex before calling any of the cancellation cleanup handlers. This is done in order to ensure that the cancellation cleanup handler is executed in the same state as the critical code that lies both before and after the call to the condition wait function. This rule is also required when interfacing to POSIX threads from languages, such as Ada or C++, which may choose to map cancellation onto a language exception; this rule ensures that each exception handler guarding a critical section can always safely depend upon the fact that the associated mutex has already been locked regardless of exactly where within the critical section the exception was raised. Without this rule, there would not be a uniform rule that exception handlers could follow regarding the lock, and so coding would become very cumbersome. Because there is no pthread_cleanup_push/pop around the pthread_cond_wait call that would unlock the mutex, the second thread is blocking on the mutex while trying to re-acquire it.
Jakub, Aha! Thank you for the quick response to our sloppy coding :-) Adding pthread_cleanup_push() and pthread_cleanup_pop() to unblock the mutex worked beautifully.