[c++-pthreads] Re: pthread_cancel and EH: let's try this again

Jakub Jelinek jakub at redhat.com
Fri Jul 15 07:22:28 UTC 2005


On Fri, Jul 15, 2005 at 12:19:38AM -0700, Mark Mitchell wrote:
> Jakub Jelinek wrote:
> >On Thu, Jul 14, 2005 at 05:24:57PM -0700, Mark Mitchell wrote:
> >
> >>Why not just have two modes, controlled by an environment variable, 
> >>link-time option, or run-time variable?  In the first mode, cancellation 
> >>would not be an exception and nothing but pthread_cleanup_push'd code is 
> >>run, and stack unwinding of all kinds is totally ignored.  In the second 
> >>mode, cancellation would be an exception; nothing more, nothing less.
> >
> >
> >There is big amount of code in Linux after a few past years that already
> >has pthread_cleanup_{push,pop} internally implemented as a C++ object
> >with a destructor.  So this is really not a workable option.
> 
> Really?

<pthread.h> has:

# ifdef __cplusplus
/* Class to handle cancellation handler invocation.  */
class __pthread_cleanup_class
{
  void (*__cancel_routine) (void *);
  void *__cancel_arg;
  int __do_it;
  int __cancel_type;

 public:
  __pthread_cleanup_class (void (*__fct) (void *), void *__arg)
    : __cancel_routine (__fct), __cancel_arg (__arg), __do_it (1) { }
  ~__pthread_cleanup_class () { if (__do_it) __cancel_routine (__cancel_arg); }
  void __setdoit (int __newval) { __do_it = __newval; }
  void __defer () { pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED,
                                           &__cancel_type); }
  void __restore () const { pthread_setcanceltype (__cancel_type, 0); }
};

/* Install a cleanup handler: ROUTINE will be called with arguments ARG
   when the thread is canceled or calls pthread_exit.  ROUTINE will also
   be called with arguments ARG when the matching pthread_cleanup_pop
   is executed with non-zero EXECUTE argument.

   pthread_cleanup_push and pthread_cleanup_pop are macros and must always
   be used in matching pairs at the same nesting level of braces.  */
#  define pthread_cleanup_push(routine, arg) \
  do {                                                                        \
    __pthread_cleanup_class __clframe (routine, arg)

/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
   If EXECUTE is non-zero, the handler function is called. */
#  define pthread_cleanup_pop(execute) \
    __clframe.__setdoit (execute);                                            \
  } while (0)
...

	Jakub



More information about the c++-pthreads mailing list