[c++-pthreads] pthread_cancel and EH: let's try this again
Mark Mitchell
mark at codesourcery.com
Mon Jul 11 20:36:22 UTC 2005
Jason Merrill wrote:
> Previous discussion on this topic ended in something of a stalemate.
Thank you for re-starting the discussion. I wasn't happy with the
stalemate, but I didn't have the fortitude to try again!
> In previous discussions, my favored solution was:
> 1a) Cancellation is disabled during stack unwinding, to avoid trying to
> throw out of a destructor.
> 1b) Make cancellation a normal exception that can be caught and discarded,
> but have the destructor for the exception re-assert cancellation so that
> the process will begin again at the next cancellation point.
I think this is a reasonable solution.
I think I'd still prefer just to have the handler catch the exception
and discard it, but not strongly enough to try to stand in the way of
progress. If you can build consensus around this option, I'll support
it fully.
Both your model, and the variant I suggest, preserve the pleasant
property that code which already handles "random" exceptions (like that
in libraries designed to plug into applications) continues to behave
reasonably well in the presence of cancellation.
Code that doesn't handle random exceptions probably doesn't handle
thread-cancellation either; if it's relying on certain functions
throwing only certain exceptions, then it's probably written to work in
a relatively controlled environment. (Of course, if it were compiled
with headers that say that cancellation point functions throw no
exceptions, then it would be completely hosed, under any of these models.)
> Then there's the Ada-equivalent model:
> 2a) Cancellation is disabled during destructors and empty exception specs.
> 2b) Cancellation exceptions are not caught by (...).
I think this ought to be considered a non-starter. Ignoring "catch
(...)" blocks in C++ is worse than just killing the thread. Style
considerations aside, there's a ton of code that relies on that to clean
up resources, or to otherwise restore state; and running destructors
after skipping "catch (...)" blocks is just plain wrong, in my opinion.
Maybe in workstation/server applications this makes sense to some
people, but I don't think it makes any sense at all on an embedded
system, where the system is often set up to handle complete process
death, but not weird inconsistencies. You'd be breaking people's
program verification regimes, as well.
> Thread robustness (catch and retry). A thread could have a catch (...)
> at the top level to try to recover from errors, on the principle that
> limping along is better than total failure. Previous discussion seemed
> to assume that the users would want this to catch cancellation as well,
> but I think that's wrong; if someone specifically told the thread to go
> away, they don't want it to recover, they want it to go away.
I agree. In fact, despite my oft-stated opinion that it should be
possible to catch cancellation exceptions, I agree that actually doing
that -- and never restarting the cancellation process -- would generally
be a bug in user code.
The reason I'm OK with catching the exception is to do things like:
try { ... } catch (Cancellation) {
cancelled = 1;
}
/* Other stuff here. We have no finally clauses in C++. */
if (cancelled) {
throw Cancellation; // Or, maybe a different exception type, that
// tells the top level to cancel the thread.
}
Your auto-recancel semantics are probably good enough in this kind of
situation.
> Ulrich Drepper insists that #1 is impossible, because pthread cancellation
> is an irreversible state change. But I'm not sure why you can't just flip
> various flags back to where they were before.
Yes, I've asked Ulrich about this several times, and have never gotten
an explanation.
> My current inclination is to go with model #2; backwards compatibility
> with code written to work with pthread_cleanup_push/pop seems like a
> powerful argument in its favor. People who want model #1 can use a
> different threading library, such as Boost.Threads.
Oh, no... I thought up until this paragraph that we were going to be on
the same page.
I think that if #1 really is impossible, #2 might be second-best. But,
I'd very much like an explanation of why #1 is impossible. While I have
very high confidence in Ulrich's technical abilities, I don't think we
should have to take his opinions on faith.
--
Mark Mitchell
CodeSourcery, LLC
mark at codesourcery.com
(916) 791-8304
More information about the c++-pthreads
mailing list