pthread_cancel and EH: let's try this again

Alexander Terekhov terekhov at web.de
Thu Jul 21 15:11:52 UTC 2005


Peter Dimov wrote:
[...]
> A simple solution is to adopt (1) and re-enable cancellation at the end of
> the catch clause.
> 
> This solution is not without its merits and is actually a workable
> approximation of the "ideal" model, but it has the following problem: the
> proper value of the cancelability state after the exception is finalized may
> be "disabled". In the example below:
> 
> // #1
> 
> try
> {
>     f();
> }
> catch( ... )
> {
> }
> 
> // #2
> 
> the cancelability state at #2 ought to be the same as the cancelability
> state at #1, provided that its only explicit manipulation is via a RAII
> guards that always restore it to its previous value.

Let the user code do it. It's not that hard.

  // #1
  int cancelstate = std::thread_cancelstate();

  try
  {
      f();
  }
  catch( ... )
  {
    stick_cancel_and_ignore_exit(cancelstate);
  }

  // #2

with 

  void stick_cancel_and_ignore_exit(int cancelstate) throw() {
    try { 
      throw; 
    } 
    catch(const thread_termination_request & request) { 
      if (cancelstate == PTHREAD_CANCEL_ENABLE)
        pthread_setcancelstate(cancelstate, &cancelstate);
      if (request.exit_value_ptr() == PTHREAD_CANCELED)
        pthread_cancel(pthread_self());
      else ; // do whatever (if anything) so that it won't leak
    }
    catch(...) { }
  }

> Remembering the state at the cancellation point doesn't work; it may've 
> been asynchronous. It may even have been disabled if the cancellation 
> exception originated from an explicit user throw.

Such explicit user throw would violate the contract. It's sorta 
like insisting that some user's operator new(size_t, const 
std::nothrow_t &) shall be able to exit with std::bad_alloc from 
explicit user throw and all should work just fine. But anyway,
see above.

> - the point of cancellation is to initiate stack unwinding, and when an
> exception is active, stack unwinding is already under way;

That's not true under standard definition of stack unwinding.

> 
> and
> 
> - given std::unfinished_exception(), the semantics of cancellation are also
> implementable in user code or libraries 

You mean wrapping all cancellation points and async-cancel 
regions with

  disable_cancel_if_uncaught_exception_returns_true guard;

objects? Ugly.

regards,
alexander.




More information about the c++-pthreads mailing list