This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [3.3] Followup to C++ forced unwinding

"William E. Kempf" <> writes:

>> What makes the proposal almost tolerable is that it is considered  best
>> practice under almost all circumstances to rethrow unidentified
>> exceptions, and the overwhelming majority of existing code does
>> so. 

And also that it doesn't cause a special case to be enshrined in the
core language definition (even if it's not the *standard* core
language, GCC will be stuck with the choices it makes for some time to

>> Code
>> that doesn't, though, tends to be that way for critically
>> important reasons which we would be foolish to second-guess.  One
>> such reason is that it is meant to be called from a language that
>> cannot handle exceptions.
> Precisely.

I third that.  

In particular, I work on a language binding library which really needs
to translate C++ exceptions into Python exceptions (which are not
exceptions at the C/C++ language level) at the language boundary.  To
get the "right" behavior, which would continue unwinding through
Python code, I *must* eat the C++ exception.  If my code doesn't know
anything specific about thread cancellation exceptions, it will try to
turn the exception into an "Unidentified" error, which will propagate
back through Python, almost certainly resulting in correct behavior.

>> What would probably be actually tolerable would be to copy some similar
>> machinery from the existing C++ runtime, such as the unexpected(). (See
>> ISO 14882, p345: section, [lib.unexpected.handler].)
>> Instead of the cancellation object's destructor registering terminate()
>> itself as the destructor, it would register another function which,  by
>> default, calls terminate().  A program may call a function
>> "set_cancellation_destructor(void (*)());" and pass it a function
>> pointer to be called instead of terminate(), normally an empty
>> function.  In that case discarding the cancellation would be like
>> discarding any other exception, and it is up to the author of the  code
>> to ensure that the thread dies on schedule.
> On what schedule?  Cooperative cancellation is a request, not a
> demand. 

That is a key point.  It seems like we're having this discussion
because even though that is a basic pthreads design decision, it is
hard for the brain to accept.

There are very few correct programs which can "eat all exceptions and
plow ahead anyway".  Is it really a design requirement that these
programs be transplantable *without modification* into an environment
where they run on a thread *and* where a thread cancellation _request_
can be assured of terminating them?
  [and I note as you mention below: there is no assurance anyway]

> Ignoring the mechanism in which cancellation is carried out, with
> the POSIX cooperative cancellation mechanism it is possible for a
> thread to be "cancelled" but still never terminate.  For instance,
> if it never calls a cancellation point, or turns off cancellation
> detection before it does, the thread can continue on indefinately,
> even though a request to be cancelled has occurred.  So, the only
> "schedule" is the explicit schedule set by the thread being
> cancelled (not the thread making the request).  Terminating (and I
> assume when you say terminate() you aren't talking about a
> thread_terminate() that would abort only the thread) in this case
> seems like a sledge hammer being used to enforce a very strict
> exception handling mechanism.  

Or rather, to bypass the EH mechanism and make "sure" (unreliably)
that the thread dies.

> I wouldn't have problems with an individual program electing to do
> this, but the library should not do this (at least by default, even
> if I can turn it off).  Forcing a re-throw would be a better
> idea... but even that was rejected during the discussion on the
> Boost list, for the reasons you gave above. IOW, it's sometimes
> valid/necessary to catch with out re-throwing

As in my Python binding case.

Dave Abrahams
Boost Consulting

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]