Email List: Xaustin-group-lX
[All Lists]

RE: XSH/XRAT conflict over cancellation points

To: Schwarz Konrad <yyyyyyyyyyyyyy@xxxxxxxxxxx>
Subject: RE: XSH/XRAT conflict over cancellation points
From: Alexander Terekhov <yyyyyyyy@xxxxxxxxxx>
Date: Fri, 21 May 2004 18:19:53 +0200
Cc: Dave Butenhof <yyyyyyyyyyyyyy@xxxxxx>, yyyyyyyyyyyyyy@xxxxxxxxxxxxx
> After pondering the issue some more, I fail to see what impact
> setjmp()/longjmp() actually have on thread cancellation.

Thread cleanup handlers can be interleaved with exception 
handlers. If you have archaic setjmp/longjmp based "C 
exceptions", you have no practical choice other than use 
TRY-CATCH{ALL} or TRY-FINALLY for pthread_cleanup_push/pop 
implementation (two separate stacks make no sense). TRY is 
nothing but decorated setjmp() and THROW/RETHROW is nothing 
but decorated longjmp().

> The cancellation stack is simply a list of routines that must be 
> invoked at certain times.

/*
 * See http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/
 */
#define pthread_cleanup_push(routine, arg) \
    { \
      scope_guard_impl const & _guard = make_scope_guard(arg, routine);

#define pthread_cleanup_pop(execute) \
      if (!execute) _guard.dismiss(); \
    }

typedef std::thread * pthread_t; // e.g.

#define PTHREAD_CANCELED std::thread_canceled()

struct thread_canceled {
  operator void * () { return &unique; }
  static thread_canceled unique;
};

class thread_termination_request : public std::exception ...
class thread_cancel_request : public std::thread_termination_request ...
class thread_exit_request : public std::thread_termination_request ...
template<typename T> class thread_exit_value : public 
std::thread_exit_request ...

extern "C" pthread_t pthread_self() throw() {
  return std::thread_self().raw_ptr();
}

extern "C" void pthread_exit(void * ptr) 
        throw(std::thread_termination_request) {
  ptr == PTHREAD_CANCELED ? std::thread_cancel() : 
                            std::thread_exit(ptr);
} 

template<typename T>
void thread_exit(T value) {
  assert(std::thread_self().can_exit_with<T>());
  throw thread_exit_value(value);
}

template<>
void thread_exit(std::thread_canceled) {
  thread_cancel();
}

void thread_cancel() {
  throw std::thread_cancel_request();
} 

Or something like that.

regards,
alexander.

<Prev in Thread] Current Thread [Next in Thread>