|
Boost : |
From: Phil Endecott (spam_from_boost_dev_at_[hidden])
Date: 2007-11-03 14:40:10
Phil Endecott wrote:
>>> Alexander Terekhov wrote:
>>>> "Gnu gcc and Solaris pthreads: The Gnu gcc and Solaris pthreads
>>>> implementations are two known implementations that attempt to map
>>>> POSIX pthread cancellation onto C++ exception handling, but both
>>>> do so at the cost of breaking the exception model (i.e., they no
>>>> longer conform to ISO C++) because the alternative appears to be
>>>> that C++ destructors and catch blocks would not be invoked for
>>>> cancellation which would mean that resources would be leaked."
>>>>
>>>> Uhmm. Don't know about (modern) Solaris, but glibc (presumably
>>>> that is meant by "Gnu gcc pthreads implementation") does invoke
>>>> C++ destructors and catch blocks.
>
> <rant>I can't believe how much time I have wasted trying to sidestep
> the need for cancellation, and investigating how to hack some
> approximation to cancellation into my application (e.g. by using
> processes and shared memory rather than threads), only to discover now
> that exactly the feature that I need is already present in glibc - just
> not documented by them.</rant>
In case anyone is curious, I have put together a simple thread class
that uses the pthread_cancel. You can see it here: http://chezphil.org/tmp/Thread.hh
I've done this mainly to prove to myself that pthread_cancel really
does invoke destructors. But I've also taken the opportunity to do a
couple of other things:
* I've written a set of scoped_* classes that change the thread
cancellation state, e.g.
{
scoped_disable_cancellation d;
non_cancellation_safe_function();
// As Dave Abrahams points out, you need this around code that relies
on catch blocks since
// the glibc pthread_cancel doesn't call them.
}
{
scoped_enable_async_cancellation e;
for (int i=0; i<1000000000; ++i) {
complex_maths(i);
}
// I imagine that only certain kinds of code can be used safely with
async cancellation.
// The example that interests me is JPEG image decoding with libjpeg.
}
{
scoped_enable_deferred_cancellation e;
code_that_does_blocking_io();
}
This would also fit with the approach that Anthony has been using,
apart from the async mode.
* I've written the thread class with its lifetime tied to the lifetime
of the thread, in contrast to Boost.Thread, which is more like a
thread-pointer. This makes a bit more sense with cancellation
available; the thread is cancelled by deleting the thread object. I'm
going to look at whether this makes for more or less convenient coding
in my applications. Of course, there's no reason why this can't
co-exist with the thread-handle approach, with one implemented in terms
of the other.
I haven't yet looked into the testcancel() problem (i.e. code that
wants to provide an explicit cancellation point needs to do so in a way
that's appropriate for the kind of cancellation in use). Anthony, do
you have any thoughts about providing a per-thread function pointer for this?
Regards,
Phil.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk