[3.3] Followup to C++ forced unwinding

William E. Kempf wekempf@cox.net
Thu May 1 22:36:00 GMT 2003


Mark Mitchell said:
>> I don't know.  I'm still trying to grasp why terminate() is considered
>> a good (or even acceptable) choice here.
>
> I suggest you go read this entire thread:
>
>   http://gcc.gnu.org/ml/gcc-patches/2003-04/msg02246.html
>
> so that you have more context.

Thanks.  I have one posting in particular that sumarizes some of what I've
been saying nicely, and allows me to make a few more observations:
http://gcc.gnu.org/ml/gcc-patches/2003-04/msg02279.html.

"I think the key design goal should be to make correct single-threaded
code usable in a multi-threaded program, with as little modification as
possible."

As I tried to point out in my last reply, this goal isn't met if
terminate() is called.  In a single threaded compile, this is safe, as
pointed out in the thread:

f = fopen(...);
try {
  foo();
} catch (...) {
}
fclose (f);

When compiled as a multi-threaded compile, it's safe only if the catch()
block is run, and terminate() is not called when a cancellation exception
is not re-thrown.  The reason is that I don't know if foo() is an implicit
cancellation point (i.e. it calls an explicit cancellation point in some
code path).

"If the catch-clause chooses not to rethrow the exception, that just
means this thread isn't going to be cancelled, which could happen from
an ordinary pthread cancellation handler.  Deferred cancellation
semantics don't give you any guarantees about when a thread will exit
after it has been cancelled."

Or even *if* it will be cancelled.

I have to leave for the night, and probably won't be able to read further
or comment more until tomorrow.  But I do have one final thought right
now.  One of the reasons given for using terminate() is that it makes it
easier for support to pinpoint the programmer error if certain routines
(long_jump() and thread_exit() were given as examples) were called after
cancellation, which is supposed to result in undefined behavior.  Well,
what prevents these from being called in destructors or other cleanup
handlers?  Why should the catch() be treated any differently than these
cases?

>> Just to make sure everyone is aware of it, Mr.Butenhof, a noted POSIX
>> threading expert, has done work on Tru64 along these very same lines
>> (http://sources.redhat.com/ml/libc-alpha/1999-08/msg00038.html).
>
> Yes, this is precisely what I, Nathan Myers, and others, have argued is
> the right answer.
>
> At this point, we're merrily going around telling each other how much we
> all agree with each other, but none of us is the person who can actually
> influence the outcome.  That's up to Ulrich Drepper, copied above, and
> he is apparently as-of-yet unpersuaded.

Well, if it helps, Tru64 is likely to be the "existing practice" that
helps to decide what I'll suggest to the C++ committee, and as near as I
can tell in my readings so far, it does not prevent the user from catching
and not re-throwing the cancellation (or exit!) exception.  So I'm likely
to suggest the same, unless it can be shown that this is technically a bad
idea.  So, I know you want to convince Ulrich Drepper that it should be as
I've described, but in trying to convince anybody, I'm turning it around
asking that you convince me it shouldn't be, or more precisely, that
calling terminate() is even viable, let alone preferred.  However, if that
is my suggestion, and the committee agrees/accepts the proposal, you'll
have to change the behavior to not terminate() at that point, anyhow.  So,
I'm providing at least some arguments to help convince people even by
this.

I'll go do my research here and continue this tomorrow.

-- 
William E. Kempf




More information about the Gcc-patches mailing list