2 * This illustrates the bug where the cleanup function
3 * of a thread may be called too many times.
10 * - register cleanup handler via pthread_cleanup_push()
11 * - try to grab mutex and sleep
15 * thread1 cleanup handler:
16 * - try to grab mutex and sleep
20 * thread1 cleanup handler:
21 * - wrongly called again
34 #define warn(fmt, args...) fprintf(stderr, "[%p] " fmt, (void*)pthread_self(), ## args)
35 #define warnf(fmt, args...) warn("%s:%i: " fmt, __FUNCTION__, __LINE__, ## args)
37 int ok_to_kill_thread
;
39 static void thread_killed(void *arg
);
41 static void *KillMeThread(void *thread_par
)
45 warnf("Starting child thread\n");
47 pthread_id
= pthread_self();
48 pthread_cleanup_push(thread_killed
, (void *)pthread_id
);
50 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS
, NULL
);
51 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE
, NULL
);
54 warnf("please kill me now\n");
56 ok_to_kill_thread
= 1;
60 pthread_cleanup_pop(0);
65 static void thread_killed(void *arg
)
67 static int num_times_called
= 0;
69 warnf("killing %p [cnt=%i]\n", arg
, ++num_times_called
);
70 assert(num_times_called
== 1);
72 /* pick any cancellation endpoint, sleep() will do just fine */
74 warnf("sleeping in cancellation endpoint ...\n");
78 warnf("done cleaning up\n");
81 int main(int argc
, char *argv
[])
84 pthread_t app_pthread_id
;
86 /* need to tweak this test a bit to play nice with signals and LT */
89 ok_to_kill_thread
= 0;
91 pthread_create(&app_pthread_id
, NULL
, KillMeThread
, NULL
);
93 warnf("waiting for thread to prepare itself\n");
94 while (!ok_to_kill_thread
)
98 warnf("killing thread\n");
99 pthread_cancel(app_pthread_id
);