Boost logo

Boost :

From: Dan'l Miller (optikos_at_[hidden])
Date: 2002-08-24 09:57:12

  As the tumult was going on, I was reading the multitude of recent "Threads & Exceptions Issue" postings.

  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:

  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)?

  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)

  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.)

  q4) If in q3 a void return-typed t is still joinable, what is to happen to t's uncaught exceptions?

  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?

  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>

  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?

  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)?

  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.

  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-fully-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.)

  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.

  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 (possibly 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?

  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.

  q14) If scenario s13 can occur, how does s catch multiple exception-type instances emanating from T? (Pursuit of this would be misguided)

  q15) If scenario s13 can occur, how does s unwind its stack multiple times as part of catching these multiple exceptions? (Pursuit of this would be misguided.)

  q16) If scenario s13 cannot occur, why not?

  q17) If scenario s13 cannot occur due to the lack of a single n+1-ary thread-join-with-T-point abstraction but rather only a n+1-member ordered set J of {thread-join-with-t-point, thread-join-with-t1-point, ..., thread-join-with-tn-point} whose members occur serially in s, and if {t, t7, t9} throw exceptions, s's stack unwinds when t's exception is conveyed (chronologically first due to first join), but then what happens to t7's uncaught exception and t9's uncaught exception? E.g., silent t7 & t9 thread exit but not process exit; process exit; t7's exception & t'9 exception shall be handled a different way than conveyance to s.

  q18) If q17 was "t7's exception & t9's exception shall be handled a different way than conveyance to s", then in reality why wouldn't that same alternative technique which was made to apply to t7 & t9 apply equally well to t in the first place? (Why have two techniques instead of one?)

  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?)

  q20) If q17's and q5's techniques (of handling uncaught exceptions emanating from threads which are no longer joinable with s) were different, why have three techniques instead of one: one for q1 (t joinable with s), one for q17 (T joinable with s), and one for q5 (threads detached/nonjoinable by design)?

Boost list run by bdawes at, gregod at, cpdaniel at, john at