Fix deadlock in timer_delete.
If the callback function for a timer did a timer_delete, the function
would never return. The problem was that the timer_delete function would try
to wait until the timer thread has finished. Waiting for yourself to finish
doesn't work very well.
Bug: 13397340
Change-Id: Ica123a5bafbc8660c8a4a909e5c2dead55ca429d
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index ffe213c..e9190b2 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -100,11 +100,14 @@
static void __timer_thread_stop(PosixTimer* timer) {
pthread_kill(timer->callback_thread, TIMER_SIGNAL);
- // We can't pthread_join because POSIX says "the threads created in response to a timer
- // expiration are created detached, or in an unspecified way if the thread attribute's
- // detachstate is PTHREAD_CREATE_JOINABLE".
- while (timer->exiting == 0) {
- __futex_wait(&timer->exiting, 0, NULL);
+ // If this is being called from within the callback thread, do nothing else.
+ if (pthread_self() != timer->callback_thread) {
+ // We can't pthread_join because POSIX says "the threads created in response to a timer
+ // expiration are created detached, or in an unspecified way if the thread attribute's
+ // detachstate is PTHREAD_CREATE_JOINABLE".
+ while (timer->exiting == 0) {
+ __futex_wait(&timer->exiting, 0, NULL);
+ }
}
}