------- 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.



Reply via email to