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
with
> >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
to
> >current C++ compilers which already support native platform
threads.
>
> >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,
and
> >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 http://www.lambdacs.com/cpt/FAQ.html#Q280
>
> 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
pthread_exit()?
>
> - 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
exception
> handling? Do the handlers get executed first and then exception
processing
> takes place? Or are they somehow nested together?
>
> - Does POSIX cleanup handling play any role in converting
cancellation
> to a C++ exception?

Useful encapsulation of most of the issues.
 
> Here are some answers from the expert.
>
> from: http://sources.redhat.com/ml/libc-alpha/1999-08/msg00038.html
>
> 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
Aug
> 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
forward
> 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()
and
> 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
C++,
> > 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
UNIX,
> is, more or
> less, your "1". Actually, "1" is what happens with the current OS
and
> 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
exceptions.
>
> I know others, though, who believe that cancellation shouldn't be
> catch-able
> (anonymously or otherwise), and should only run destructors. That's
your
> "2". I don't
> know of anyone who believes that cancellation shouldn't be required
to
> 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
with
> > the implementation, and if I recompile the C library with
exception
> > 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
time
> an exception
> propagates through the code scope.) I don't believe it's acceptable
to
> 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
run
> the object
> destructor. On normal exit, it would check the pop argument to
determine
> whether to
> call the cleanup handler; otherwise it'd always call the handler.
But
> 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
underlying
> 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++
solution.

[the rest snipped as not relevant to the discussion]

Bill Kempf


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