Boost logo

Boost :

From: bill_kempf (williamkempf_at_[hidden])
Date: 2002-01-17 12:22:19

--- In boost_at_y..., Lee Brown <lee_at_a...> wrote:
> >Are you proposing that cancel_push, cancel_pop, goto statements
> >explicit cleanups, and a ban on objects with destructors on the
stack is
> >more handsome and convenient than using exceptions**, or have I
misread you?
> I don't know if I was clear or not. (BTW: errno IS thread specific)

No, it's not. POSIX, I believe, enforces this, but it's not
universal to other platforms, nor required by the language standard
(which is all that really matters here).

> But your
> statements made me do my homework and search the web for
the "right" answer.
> In short, the issue is confused and Beman was right when he said..
> >AFAIK, however, the current Boost.Threads does not require changes
> >current C++ compilers which already support native platform
> >That makes it a MUCH easier to sell to the compiler vendors, who
are well
> >represented on the committee.  They can see that it already works,
> >already works with their compiler.  It also means users can
benefit today,
> >rather than having to wait for years.
> >--Beman  
> Here is what the most involved think.
> from
> Q280: C++ exceptions in a POSIX multithreaded application?
> ...
> The questions are:
> - What exception is the cancellation request turned into in the
target thread?
> What is the exception's type? What header should it be defined in?
> - Upon catching the exception, what steps does the target thread
take to
> terminate itself? Just re-enter the threads code by calling
> - Are the handlers for unhandled and unexpected exceptions global or
> thread specific?
> - Do unhandled cancellation exceptions terminate the entire process?
> - By what interface does the process arrange for cancellations to
turn into
> C++ exceptions?
> - What is the interaction between POSIX cleanup handlers and
> handling? Do the handlers get executed first and then exception
> takes place? Or are they somehow nested together?
> - Does POSIX cleanup handling play any role in converting
> to a C++ exception?

Useful encapsulation of most of the issues.
> Here are some answers from the expert.
> from:
> FWD: Dave Butenhof (author of Programming with POSIX Threads) on
C++ and
> pthread_cancel()
> To: gcc_at_g..., libc-alpha_at_s...: FWD: Dave
> Butenhof (author of Programming with POSIX Threads) on C++ and
> pthread_cancel()From: "George T. Talbot" <george_at_m...>Date: Thu, 19
> 1999 11:37:08 -0400CC: Ulrich Drepper <drepper_at_c...>, Dave Butenhof
> <David.Butenhof_at_c...>, george_at_m...: Moberg Research,
> Inc.
> I've got this book called "Programming with POSIX Threads" by Dave
> Butenhof. It's really good, so I thought I'd run the whole thread
> cancellation issue past him. I asked him if it would be OK to
> his reply to the lists, and he said it was OK, so here it is...
> --
> George T. Talbot
> <george_at_m...>
> P.S. From what I can glean from replies on the list, the current
> thread-safe exception model in GCC does not use setjmp()/longjmp()
> doesn't have runtime cost for declaring an exception scope.
> -------- Original Message --------
> Subject: Re: Question about your book...
> Date: Wed, 18 Aug 1999 13:59:48 -0400
> From: Dave Butenhof <David.Butenhof_at_c...>
> Organization: Compaq Computer Corporation
> To: "George T. Talbot" <george_at_m...>
> References: <XFMail.990603144303.george_at_m...>
> <3758014E.51BFC7C3_at_c...> <37BADDE2.205C9974_at_m...>
> "George T. Talbot" wrote:
> > Dear Mr. Butenhof,
> >
> > I've contacted you before on the issue of thread cancellation and
> > and I have another question, if you don't mind.
> >
> > I've been revisiting thread cancellation and C++ on Linux. What
is the
> > correct behaviour for C++ when a thread is cancelled? I.E. In
an ideal
> > world what effect on C++ code should pthread_cancel() in deferred
> > cancellation mode have?
> >
> > 1) Run all the destructors for objects on the stack and all code
in the
> > catch (...) handlers?
> > 2) Run all the destructors for objects on the stack?
> > 3) Nothing?
> > 4) Segfault? ;^)
> Yes, in an ideal world, all actions would segfault. That would make
> coding and
> debugging easy. (Write anything. It segfaults. Good; it was
supposed to.
> Done with
> that. On to the next project. ;-) )
> MY ideal behavior, and the one towards which I'm working on Tru64
> is, more or
> less, your "1". Actually, "1" is what happens with the current OS
> C++ release.
> We're working on moving beyond that to make cancellation (and other
> system/thread
> exceptions) known C++ exception classes so that you could write
> something like
> "catch(POSIX_cancel) {}" instead of anonymously catching all
> I know others, though, who believe that cancellation shouldn't be
> catch-able
> (anonymously or otherwise), and should only run destructors. That's
> "2". I don't
> know of anyone who believes that cancellation shouldn't be required
> run
> destructors. (And if there are any, they're wrong.) Although I don't
> agree with the
> idea of "hiding" cancellation exceptions, at least "2" would allow
> writing cancel-safe
> code.

Except in the case pointed out in this thread where catch(...) is
used to cleanup resources instead of a destructor. Which is a valid
C++ idiom that we can't ignore.
> So I'd have to say that 1 is "near-ideal" (but not as good as making
> cancel a real C++
> exception), 2 is "acceptable". The others are not.

So, the expert agrees with everything we've said here.
> > Right now, pthreads under Linux does 3. I've been fooling around
> > the implementation, and if I recompile the C library with
> > support (-fexceptions), and have pthread_cancel() do a throw as
its last
> > action after running the cancellation handlers, I can get it to
do 1).
> Interleaved C++ destructors and POSIX cleanup handlers should be
run in
> proper nested
> order, from inner to outer, in one pass. (They're not "cancellation
> handlers", by the
> way, because they're also run by thread exit, and should be run any
> an exception
> propagates through the code scope.) I don't believe it's acceptable
> run all cleanup
> handlers first, then all destructors... or vice versa. Ideally,
both are
> implemented
> as exception handlers, and the exception propagates normally as one
> would expect an
> exception to propagate.
> One option, when you're using just C++, is to have
> pthread_cleanup_push() to expand to
> a block containing a local object with a destructor. The
> pthread_cleanup_pop() macro
> would expand to terminate the block. Exiting the scope would then
> the object
> destructor. On normal exit, it would check the pop argument to
> whether to
> call the cleanup handler; otherwise it'd always call the handler.
> that won't help
> if you have interleaved C and C++ code, unless both languages
support a
> common
> exception model. That's what we do on Tru64 UNIX, because the
> common
> calling standard supports exceptions, and the C compiler provides
> extensions to
> declare essentially try/catch scopes.

This is valid for POSIX, but not necessarily for the C++ standard.
In any event, this all requires compiler support and so is not
relevant to Boost.Threads. We can't portably interleave destructor
calls and pthread cleanup handlers. Nor is there any compelling
reason to include a concept such as cleanup handlers in a C++

[the rest snipped as not relevant to the discussion]

Bill Kempf

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