Re: [c++-pthreads] Re: thread-safety definition
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [c++-pthreads] Re: thread-safety definition



> > This cannot happen if cancellation is automagically disabled during
> > execution of (all) destructors, along with the stack unwinding code
> > that is performed during exception processing.
> 
> Except that it would pretty much preclude SAFE exploitation of 
> cancellation in the destructors (stuff ala "~temp_dataset()" which 
> can simply catch cancel request exception and "re-enable/re-inject"). 

There is no need for a destructor to be aware of cancellation.
Either the cancellation happens before the destructor, and the
destructor executes as part of the cancellation processing
(obliviously), or if the cancellation is called for while a
destructor is executing (or an exception propagating) the
cancellation processing begins after destructor has finished
(or the exception has been handled successfully).

The issues of delaying processing the cancellation is not
significant here, because you will need to finish executing the
destructor in any case.  Even in the case of some (other)
exception being in flight, it makes sense to allow the other
exception processing to finish before cancelling (even if
the other exception ends up terminating the thread).

> Burning processing cycles on cancel enable/disable is another issue 
> here, BTW. 

Yes, but it need not be a *huge* amount of cycles.  Protection
against cancellation can be done via the equivalent of setting one
bit in a thread descriptor.  The cancellation protection bit is
per-thread, and only accessed by the thread itself, and so does
not require any form of lock to protect it.  Likewise, a pending
cancellation bit is per-thread and monotonic, so though it may be
set from zero to one by any thread, it does not need a lock.
Protection can be done very efficiency if the compiler knows how
to get the current thread's descriptor efficiently.  For example,
on Solaris threads this can be done as a single store operation
(there was, maybe still is, a register that always points to a
per-thread location that can be used with appropriate offset to
access such state).  Unprotecting takes a bit longer, since you
also need to check whether cancellation has been attempted while
the protect bit was set, essentially a load, store, and
conditional branch.

You can also cut it down by doing only one disable/enable pair
per *chain* of destructors, when you have a bunch of them being
executed together.

BTW, on general principles one generally would not like to have
cancellation occur during operations that manipulate global storage,
and in particular during execution of destructors.

> Intelligent cancellation that would check the dynamic 
> context (2-pase ES with exception specs acting like "fences" NOT 
> causing unnecessary unwinding) would work much better, I guess.
> 
> regards,
> alexander.

--Ted