pthread_cancel and EH: let's try this again

Alexander Terekhov terekhov at web.de
Mon Jul 18 22:52:42 UTC 2005


Wil Evers wrote:
[...]
>
> X::~X()
> {
>         try {
>                 cancellation_manager enabler(true);
>                 some_blocking_operation();
>         } catch (const cancellation & ex) {
>                 // log ex
>                 // don't rethrow
>         }
> }

Nope. It will break X's client logic relying on modularity of X in the 
sense of its capability to defer cancellation and perform cancelable
effects (subject any other failure modes, if any) when cancellation is 
been disabled by X's client. In verbose form, you probably want this:

void some_cancelable_cleanup_operation() throw(X, Y, Z, cancellation);

X::~X() throw() {
  // Unwinding caused by cancellation delivery?
  if (unwinding(this) && active_exception<cancellation>(0)) {
    pthread_cancel(pthread_self());
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &errno);
    try {
      // "shall occur" (apart from X, Y, Z) cancellation point 
      some_cancelable_cleanup_operation(); 
    }
    catch(const cancellation &) {
      // don't rethrow
    } 
    catch(...) { // X, Y, Z
      pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &errno);
      // log ex
      // don't rethrow
    }
  }
  else {
    try {
      some_cancelable_cleanup_operation(); 
    }
    catch(const cancellation &) {
      pthread_cancel(pthread_self());
      pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &errno);
      // don't rethrow
    } 
    catch(...) { // X, Y, Z
      // log ex
      // don't rethrow
    }
  }
}

regards,
alexander.




More information about the c++-pthreads mailing list