------- Comment #17 from redi at gcc dot gnu dot org 2010-09-10 10:11 ------- (In reply to comment #15) > In particular, it does not appear that the thread is being reliably cancelled > at the pthread_testcancel call - sometimes f2 seems to run beyond the > pthread_testcancel,
As I said above, that's consistent with f2(50) executing before pthread_cancel. > which causes the throw to execute, and results in an abort > (seems to want to act like an uncaught exception propagated out). If you > comment out the throw, f2 will sometimes continue to construct additional > objects past 50. I have also noticed that sometimes a bunch of the Y objects > get destructed, but then the program suddenly summarily exits. I think that's because f2(50) leaves cancellation enabled and writing to cout is a cancellation point, so the exit happens when some ~Y destructor coincides with thread2 calling pthread_cancel. > I also tried > setting the cancellation type to asynchronous, but that doesn't make any > difference - sometimes it works, sometimes it don't. Its very unpredictable. Yes, race conditions tend to have unpredictable results. If I change the condition in f2 to (i >= 50) and disable cancellation again after the call to pthread_testcancel then I get more predictable behaviour, because that ensures that the only cancellation points are the calls to pthread_testcancel in f2, which still occur in f2(51), f2(52) etc. i.e. cancellation still occurs at the intended place even if f2(50) happens before the call to pthread_cancel. That seems to validate my theory that the cancel happens after f2(50), and so takes effect at the first cancellation point after the cancellation request. I don't think there's a gcc or glibc bug here, just non-portable code with indeterminate behaviour. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45479