exceptions and threads

Christian Millour chris161@club-internet.fr
Fri Dec 12 13:04:00 GMT 1997

> Date: 11 Dec 1997 09:56:34 -0000
> From: Wolfram Gloger <wmglo@dent.med.uni-muenchen.de>
> Sender: owner-egcs@cygnus.com
> Precedence: bulk
> Reply-To: egcs@cygnus.com
> X-UIDL: 7f68112b4458960e1e914811c98022a2
> >   In message < 199712092333.AAA02615@riva.nowhere >you write:
> >   > Hi all. I was wondering whether signalling a thread could be
> >   > converted safely into a C++ exception. My gut feeling is that
> >   > it cannot, but I'd like your compiler experts confirmation. 
> jeff wrote:
> > Can you provide more details about what this really means.
> > 
> > Does this imply that exceptions can happen basically anywhere in
> > a program (as opposed to exceptions in C++ which happen at distinct
> > points (either a throw point or at function call points)

Sorry Jeff, I didn't see your direct answer. Anyway, in the meantime
I've done a lot of reading and can indeed provide a few more details
as well as a fixed terminology :-)

The following is digested from the excellent "Programming with Posix
threads" by Dave Butenhof:

with pthreads, what happens after a pthread_cancel depends on the
state (enable/disable cancellations) and type (deferred/asynchronous
cacellation) of the receiving thread. This results in three modes

Mode          State      Type             Meaning
Off           disabled  either   Cancellation remains pending till enabled
Deferred      enabled  deferred  Canc. occurs at next `cancellation point'
Asynchronous  enabled   async.   Canc. may be processed at any time. 

`cancellation points' are functions (such as read, write, etc.),
typically (but not only) those that may block for an arbitrary period
of time. pthread_testcancel() is a pure cancellation point that one
may use to turn an arbitrary function into a cancellation point. A
region of code may be protected from cancellation (e.g. to ensure that
related updates are performed).

Asynchronous cancellation is dangerous and its use should probably be
restricted to tight computation loops in which the overhead of calling
pthread_testcancel() would be severe. It may occur at any hardware
instruction (maybe in the middle of a hardware instruction on some
architectures). As a consequence no resource should ever be acquired
while in async. cancel mode. 

end of digest.

> What might be meant is that the cancellation of a thread as defined by
> the pthreads standard is _exactly like_ an exception.

rather a non-catchable-by-the-cancelled-thread exception (see below)

>                                                       On the two most
> advanced platforms for multithreaded programming, Solaris 2.6 and
> Digital Unix-latest, when you cancel a thread that is running C++
> code, destructors are automatically invoked and the stack is unwound
> until the thread entry point (the function handed to
> pthread_create()).

This is cool and the way it should be... Does it work even in Async 
Cancel mode ? 

> This is a _really_ nice feature, although no standard specifies it yet
> (pthread itself only specifies cleanup handlers, which are rather
> restricted due to the C interface).

This is not only nice, it is probably the only way to go. The
alternatives are almost too ugly to mention. You'd have to register
every resource allocation into an external registry, and perform
cleanup afterwards. Ouch!

Picture an application split up simply into one processing thread, and
one user interface thread. The processing thread may proceed for
hours, and one functionality of the user interface is to provide a way
to cancel gracefully the current work. The processing thread is of
arbitrary complexity, may allocate various kinds of resources,
etc. How do you interrupt it ?

One way without cancel is to have the processing thread periodically
test an interruption flag and throw an exception on success. This
generates a lot of pollution in the processing code.

The elegant alternative is to cancel the processing thread, and have
the cancellation proceed as if an exception had been thrown, except
that this exception should not be catchable within the cancelled
thread itself (to quote DB again, cancellation is not a communication
mechanism; there's also the problem of exception specifications, as
the cancellation might have to traverse a call to a function such as
void foo() throw(); ). This provides for easy cleanup, and makes
multithreading orthogonal to programming (well, almost, in the same
sense that exceptions make error handling othogonal with the coding of
the `nominal' behavior).

>                                      It would be great to have it
> available with egcs, although some cooperation with the pthread
> implementation is probably unavoidable, so it may be hard; but I think
> it should be doable at least for glibc2.

If it's been done by Sun and Digital, I certainly hope it will be done
some day for egcs and glibc :-)

It's too bad that the Posix Threads and C++ standardisations have so
far AFAIK so pointedly ignored each others : no C++ API for pthreads,
and no awareness of threads in C++. Sigh. (I'd love to be corrected on
both counts).

Back now to the original question, wich pertains essentially to the
Asynchronous Cancellation mode. Since in that case cancellation may
occur at any hardware instruction, is it indeed possible to handle it
as if a (non-catchable?) exception had been thrown, i.e. by unwinding
the (thread) stack and invoking the destructors ? If the answer is
yes, where should I look in egcs code to understand how it is (or
could be) done ?

Thanks for your time and attention. 


> If anyone is interested, I have saved some postings from Dave Butenhof
> on comp.programming.threads as to how this works on Digital Unix.

I've read a lot of Dave's posts on c.p.t but might have missed a
few. Could you please email those to me ? Thanks in advance. 

> Regards,
> Wolfram.
> -- 
> `Surf the sea, not double-u three...'
> wmglo@dent.med.uni-muenchen.de

More information about the Gcc mailing list