From: Anthony Williams (anthwil_at_[hidden])
Date: 2002-08-27 05:34:42


Dan'l Miller writes:
> Although much debate occurred with many back-and-forth discussions, I
> never saw a clear & concise conclusion stating "Boost.threads shall do
> this" and "Boost.threads shall not do that" design decisions. Because
> those tumultuous threads have faded out
> , I assume that the topic has been discussed to the Boost community's
> satisfaction and that a complete set of conclusions was reached. I am
> interested in what the conclusions to the following topics were:

I am not entirely certain what Bill stated he was going to implement, but I'll
answer the questions anyway. Consequently, these answers reflect my opinions.
 
> q1) Is Boost.threads going to pursue any kind of conveyance of an
> exception thrown and not caught on a thread t back to the thread s which
> started t (i.e., conveyance as an exception-type instance, not expressed
> as an instance of a return type)?
 
Some form of conveyance, yes, but not necessarily back to the thread s that
started thread t.
 
> q2) If q1 is yes, in which circumstances? (e.g., in the case that s
> started t via a non-void template-parameter for the return-type concept)

In the circumstances that thread.join() is called for thread t. Some people
advocate that void-returning threads shouldn't propagate exceptions, but I'm
not sure I agree. In any case, I think all joinable threads should propagate
exceptions. If void-returning threads are not joinable, so be it.
 
> q3) If the criterion in q2 which precipitates conveyance of an uncaught
> exception on t is in fact a non-void template-parameter for the
> return-type concept, would t be joinable (as a chronologically-oriented
> boolean condition) if the return-type were
> void? (I suspect not, even though this occurs in existing MT practice.)

I hope not.
 
> q5) If in q3 a void return-typed t is not still joinable (i.e., t is a
> detached thread whose lifetime semantics are either 5a) run until
> end-of-process or 5b) run until t decides to end its own life), what is
> to happen to the nonjoinable t's uncaught
> exceptions?

Uncaught exceptions in non-joinable threads must terminate the process.

> q6) Is a void return-typed t the only way to create a detached thread
> which is not to be joined? If not, compare & contrast a void return-typed
> t semantics with a detached-the-other-way t<sub>1</sub>

Unspecified

> q7) For a detached t which by app-domain design is not to be joined, if t
> has an uncaught exception and if q1 is yes, does the detached-by-design t
> still convey the exception back to s?

Uncaught exceptions in non-joinable threads must terminate the process.

> q8) If q1 is yes, exactly which type is thrown in s (e.g., the same type
> as in t; all exception types thrown and not caught in t conflate to a
> single exception type in s)?

Unspecified, though we would hope that the re-thrown exception would match the
original as closely as possible --- maybe by providing a
thread_clone_exception() function.

> q9) If in q8 t's uncaught exception-type type is (re)thrown in s, exactly
> how would the exception be conveyed from t to s? E.g., if t's uncaught
> exception itself is the instance to be conveyed to s, then how would
> Boost.threads ensure that unwinding
> t's stack does not destroy t's exception instance.

t.join() would throw, rather than returning. Saving the exception instance is
unspecified, and depends on the conveyance mechanism.

> q10) If in q8 t's uncaught exception-type is (re)thrown in s but a new
> instance of t's uncaught exception-type is instantiated for s as part of
> the mechanism of how the interthread exception conveyance is
> accomplished, how does t convey that most-full
> y-derived type information to s? (Having merely a reference to
> ::std::exception in t does not tell anything about how to invoke a
> copy-ctor for the most-fully-derived type.)

Unspecified.
>
> q11) If q1 is yes, at which point would the interthread
> exception-conveyance from t ingress s? E.g., any old place; at the
> thread-join-with-t point; at a set of specially-picked standard C++
> library invocations.

At t.join()
 
> q12) If q1 is yes and q11 is the thread-join-with-t-point in s and if
> (re)throwing t's exception-type instance (uncopied) in s is the intended
> interthread exception-instance conveyance mechanism, how is t's
> exception-type instance preserved for (possi
> bly long) periods of time until s reaches the join point because t might
> have thrown before (and maybe quite a long time before) s reaches its
> join-point with t?

Unspecified.
 
> s13) If q1 is yes and q11 is the thread-join-with-t-point in s, then let
> us consider a still more troublesome case where s did not merely start a
> single thread t, but also n other threads too which are all to be joined
> back to s at a thread-join-with-
> T-point. In this case s started n+1 threads: T={t, t1, t2, ..., tn}. Let us
> consider the case where two or more threads in T experience trouble which
> is out of their league and thus two or more threads in T have uncaught
> exceptions which by q1 s would
> need to handle and by q11 would ingress s at the thread-join-with-T-point.

You can only join one thread at a time. If you join a thread with an uncaught
exception, the join operation throws. It is up to you to ensure that you
handle the exception and join other threads, if necessary.
 
> q16) If scenario s13 cannot occur, why not?

See above.
 
> q19) In reality why wouldn't q5's technique for handling an uncaught
> exception thrown in a nonjoinable t apply equally well to handling an
> uncaught exception thrown in a joinable t as well? (Why have two
> techniques instead of one?)

So you can get meaningful info from joinable threads, which have a
well-defined place at which to retrieve that information --- the call to
thread.join(). Non-joinable threads have no defined point at which to transfer
the information. If you want to do so, it is trivial to add a catch block to
the thread function, to store any relevant information before terminating the
thread, or whatever.

Anthony