[c++-pthreads] Re: pthread_cancel and EH: let's try this again

Mark Mitchell mark at codesourcery.com
Thu Jul 21 00:42:57 UTC 2005


Nathan (Jasper) Myers wrote:
>  * During the lifetime of C, the semantics of destructors and catch 
>    blocks are undefined if the thread is cancelled and a POSIX C 
>    cancellation point is encountered.  Any cleanup ends at the scope 
>    of C, and control leaves this scope via an ordinary exception.
>    
>  * Outside the scope of a cancellation_context, the effect of 
>    pthread_cleanup_push etc. is undefined.

It sounds like you're coming up with entirely new thread semantics that 
have nothing much to do with POSIX thread cancellation, in that they 
seem to leave the POSIX thread cancellation behavior undefined.

The "pthreads" in "c++-pthreads" is specifically because the charter for 
this list is to work out how to combine C++ and *POSIX* threads.  Any 
proposal that does not handle POSIX threads is out-of-scope.  If you can 
generalize that to handle all threads, great -- but the primary goal is 
to determine the behavior of a C++ program that uses POSIX threads.

For example, this program presently works on GNU/Linux (tested on RHEL 3):

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void* thread_main (void *arg) {
   try {
     fprintf (stderr, "thread: Alive.\n");
     sleep (2);
     pthread_testcancel ();
   } catch (...) {
     fprintf (stderr, "thread: In handler.\n");
     throw;
   }
   fprintf (stderr, "thread: Not cancelled?\n");
   return NULL;
}

int main () {
   pthread_t thread;
   fprintf (stderr, "main: Creating thread\n");
   pthread_create (&thread, NULL, &thread_main, NULL);
   sleep (1);
   pthread_cancel (thread);
   pthread_join (thread, NULL);
   fprintf (stderr, "main: Exiting\n");
}

and prints:

main: Creating thread
thread: Alive.
thread: In handler.
main: Exiting

Most users seem reasonably happy with this behavior.

However, if you remove the "throw;" in the handler, the program aborts:

main: Creating thread
thread: Alive.
thread: In handler.
FATAL: exception not rethrown
Aborted

Nobody likes this behavior.

Jason's approach #2 changes the behavior of the unmodified program so 
that the handler is ignored, but destructors continue to be run.  I 
don't think anybody except Jason has argued in favor of this proposal, 
and even Jason seemed to have misgivings.  Absent intervention from 
Jason, I'm assuming that idea is no longer under consideration.

So, I think we should assume the unmodified program continues as it 
presently does, maintaining compatibility with current GNU/Linux.

That means that the most important question we should answer is what to 
do for the program above, when the "throw;" is removed.

I think the only reasonable choices are:

1) Fall off the end of the catch clause in the usual way, but the thread 
is still cancelled.  Encountering another cancellation point will result 
in re-raising the cancellation exception.

2) Fall off the end of the catch clause in the usual way, but the thread 
is no longer cancelled.  It can be re-cancelled, but until it is, it 
will operate normally.

-- 
Mark Mitchell
CodeSourcery, LLC
mark at codesourcery.com
(916) 791-8304



More information about the c++-pthreads mailing list