[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