Boost logo

Boost :

From: David Bergman (davidb_at_[hidden])
Date: 2002-08-09 12:45:20


Eric,

Yes, "main" has ended, but the underlying thread has not at that stage,
the last few nanoseconds will be spent in the terminate_handler. So,
that is what I meant by "should be". Again, I am not saying that *I*
think it should be, rather that The Standards states it should...

When I use the word terminate, I always mean the thread (no matter
whether the thread is implicit as in the "program" wordings of The
Standard or explicit as in our multi-thread discussion).

However, what I was trying to say, in a quite cryptic manner, was that
the Boost.Threads should *always* use your kind of wrapper
(boost::function0 - based), to ensure that *the specific thread* obeys
the "terminate when unexpected exceptions are thrown" dogma of The
Standard. And, yes, one can of course override that behavior, by setting
the unexpected_handler, which also needs to be handled (a totally
different story...)

So, in short: I am in favor of having boost::thread always wrapping the
passed function in your kind of "try { } catch (}" boost::function0
object. That behavior is as much in pair with The Standard as anything
else. Then we can safely use 3rd party libraries that use threads (at
least our Boost.Threads...).

NOTE: the C++ standard discusses a language; we deal with programs using
that language BUT also add a thread dimension by OS-specific means, so
we deal with another language (MT-C++).

This is different from languages where threads are included, such as
Java (don't hate me for mentioning that language...), or where such
concurrency does not affect the semantics, such Haskell.

/David

-----Original Message-----
From: boost-bounces_at_[hidden]
[mailto:boost-bounces_at_[hidden]] On Behalf Of Eric Woodruff
Sent: Friday, August 09, 2002 1:12 PM
To: boost_at_[hidden]
Subject: [boost] Re: Re: Re: Re: Threads & Exceptions

I don't understand. If an uncaught exception is propagated all the way
out
of main, what is the emphasis on "should be" in "should be terminated
when
an uncaught exception is thrown"? It (main) has terminated once an
exception
is thrown that far, and since the standard follows one of the most
illogical
naming schemes, it calls terminate () instead of terminated (). Here the
naming error is that terminate () is an observation, not a command
(passive
vs active)--as far as I know.

In the example:

int main () {
    throw "no handler for me :(";
    return 0;
}

If terminate () does nothing, the program will still exit, but in a
seemingly error-free fashion, correct?

"In the situation where no matching handler is found, it is
implementation-defined
whether or not the stack is unwound before terminate() is called. In all
other situations, the stack shall

not be unwound before terminate() is called."

Hrm, what is the state of the stack for the end-user's perspective? It
seems
like main () would have to have already unwound no matter what. So the
statement in the standard only dictates what happens behind the scenes,
in
the language implementation?

On another note: One could easily write a thread specific unexpected
handler
for the thread that is even just another user boost::function which
would be
called in the event of an unlisted exception as long as the thread wraps
the
execution of the user boost::function (as in my code example).

----- Original Message -----
From: David Bergman
Newsgroups: gmane.comp.lib.boost.devel
Sent: Friday, 2002:August:09 12:30 PM
Subject: RE: Re: Re: Re: Threads & Exceptions

Bill,

You are totally right in that in order to comply with the C++ standard,
any uncaught exceptions need to implicitly invoke the registered
"unexpected_handler" for the "program", and the default implementation
of that handler would then invoke the registered "terminate_handler".

The "only" problem is what is meant by "program". A plausible mapping of
the C++ mono-threaded standard would be to project "program" onto
"thread", in which case one would need thread-specific
"unexpected_handler" and "terminate_handler" registries.

Another projection, which is the one you propose, is onto "OS process".

I am quite confident that the C++ standard means that the *current
(implicit) thread of execution* should be terminated when an uncaught
exception is thrown (with the default handlers, at least). If you have
further information underlining your projection, so that The Standard
really meant for the complete OS process to end (by default) as soon as
an uncaught exception occurs in any thread, I give in, at least with
regards to "standard compliance"; although I would still argue that it
still is quite irrational (but that is just my Extremely HO).

My projection of "program" would require the thread layer to catch any
exception and use the thread-specific "unexpected_handler". That would
in fact require the handler registry to be extended so that each entry
essentially is a map from thread Ids to a real handlers. One way to
accomplish this is to override the default handlers (with set_terminate
and set_unexpected) and making those default handlers bifurcate into the
thread-specific handlers, thereby having the resulting handler
registries work as the C++ standard states, but with one handler vector
per thread.

The standard aside, do you consider it to be logical that an uncaught
exception in a progress updating thread in our 40-thread (SuperServer)
program would cause the whole program to cease? And, do you consider
that to be coherent with what the standard states? This is where we
disagree.

We have the luxury to choose the projection of "program" here, so let's
do it in a sound manner.

/David

-----Original Message-----
From: boost-bounces_at_[hidden]
[mailto:boost-bounces_at_[hidden]] On Behalf Of William E. Kempf
Sent: Friday, August 09, 2002 9:45 AM
To: boost_at_[hidden]
Subject: Re: [boost] Re: Re: Re: Threads & Exceptions

----- Original Message -----
From: "David Bergman" <davidb_at_[hidden]>

> I totally agree that the procedural semantics should resemble that of
> the C++ standard as much as possible, but the freedom of
interpretation
> (i.e., the variety of possible mappings of the mono-threaded semantics
> to the multi-threaded "reality") should be acknowledged. Thus, the
> question whether something "complies" should be open for (a creative)
> discussion.

Again, the problem is that the underlying thread APIs don't specify what
happens in this case, while the C++ standard clearly does. So the
choice is
to obey the standard, or invoke what's not only undefined by the
standard,
but also by the threading APIs.

Bill Kempf
_______________________________________________
Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost

_______________________________________________
Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost

_______________________________________________
Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk