Unix/Linux Go Back    

RedHat 9 (Linux i386) - man page for pthread_cleanup_push (redhat section 3)

Linux & Unix Commands - Search Man Pages
Man Page or Keyword Search:   man
Select Man Page Set:       apropos Keyword Search (sections above)


       pthread_cleanup_push,	      pthread_cleanup_pop,	   pthread_cleanup_push_defer_np,
       pthread_cleanup_pop_restore_np - install and remove cleanup handlers

       #include <pthread.h>

       void pthread_cleanup_push(void (*routine) (void *), void *arg);

       void pthread_cleanup_pop(int execute);

       void pthread_cleanup_push_defer_np(void (*routine) (void *), void *arg);

       void pthread_cleanup_pop_restore_np(int execute);

       Cleanup handlers are functions that get called when a thread terminates, either by calling
       pthread_exit(3)	or  because  of  cancellation. Cleanup handlers are installed and removed
       following a stack-like discipline.

       The purpose of cleanup handlers is to free the resources that a thread  may  hold  at  the
       time  it  terminates.  In  particular,  if  a thread exits or is cancelled while it owns a
       locked mutex, the mutex will remain locked forever and prevent other threads from  execut-
       ing  normally.  The best way to avoid this is, just before locking the mutex, to install a
       cleanup handler whose effect is to unlock the mutex. Cleanup handlers can  be  used  simi-
       larly to free blocks allocated with malloc(3) or close file descriptors on thread termina-

       pthread_cleanup_push installs the routine function with argument arg as a cleanup handler.
       From  this  point  on  to  the  matching pthread_cleanup_pop, the function routine will be
       called with arguments arg when the thread terminates, either through pthread_exit(3) or by
       cancellation.  If  several  cleanup  handlers are active at that point, they are called in
       LIFO order: the most recently installed handler is called first.

       pthread_cleanup_pop removes the most recently installed cleanup handler.  If  the  execute
       argument  is  not  0,  it  also executes the handler, by calling the routine function with
       arguments arg.  If the execute argument is 0, the handler is only  removed  but	not  exe-

       Matching  pairs	of  pthread_cleanup_push  and  pthread_cleanup_pop must occur in the same
       function, at  the  same	level  of  block  nesting.   Actually,	pthread_cleanup_push  and
       pthread_cleanup_pop  are  macros,  and the expansion of pthread_cleanup_push introduces an
       open brace { with the matching closing brace } being introduced by the  expansion  of  the
       matching pthread_cleanup_pop.

       pthread_cleanup_push_defer_np	 is    a    non-portable    extension	 that	 combines
       pthread_cleanup_push and pthread_setcanceltype(3).  It pushes a cleanup	handler  just  as
       pthread_cleanup_push  does,  but  also  saves the current cancellation type and sets it to
       deferred cancellation. This ensures that the cleanup mechanism is effective  even  if  the
       thread was initially in asynchronous cancellation mode.

       pthread_cleanup_pop_restore_np	  pops	   a	 cleanup     handler	 introduced    by
       pthread_cleanup_push_defer_np, and restores the cancellation type to its value at the time
       pthread_cleanup_push_defer_np was called.

       pthread_cleanup_push_defer_np  and  pthread_cleanup_pop_restore_np  must occur in matching
       pairs, at the same level of block nesting.

       The following sequence

	      pthread_cleanup_push_defer_np(routine, arg);

       is functionally equivalent to (but more compact and more efficient than)

	      { int oldtype;
		pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
		pthread_cleanup_push(routine, arg);
		pthread_setcanceltype(oldtype, NULL);



       Xavier Leroy <Xavier.Leroy@inria.fr>

       pthread_exit(3), pthread_cancel(3), pthread_setcanceltype(3).

       Here is how to lock a mutex mut in such a way that it will be unlocked if  the  thread  is
       canceled while mut is locked:

	      pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
	      /* do some work */

       Equivalently, the last two lines can be replaced by


       Notice  that  the  code above is safe only in deferred cancellation mode (see pthread_set-
       canceltype(3)).	In asynchronous cancellation  mode,  a	cancellation  can  occur  between
       pthread_cleanup_push   and   pthread_mutex_lock,   or   between	pthread_mutex_unlock  and
       pthread_cleanup_pop, resulting in both cases in the thread trying to unlock  a  mutex  not
       locked  by  the	current  thread. This is the main reason why asynchronous cancellation is
       difficult to use.

       If the code above must also work in asynchronous cancellation mode, then it must switch to
       deferred mode for locking and unlocking the mutex:

	      pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
	      pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
	      /* do some work */
	      pthread_setcanceltype(oldtype, NULL);

       The  code  above can be rewritten in a more compact and more efficient way, using the non-
       portable functions pthread_cleanup_push_defer_np and pthread_cleanup_pop_restore_np:

	      pthread_cleanup_push_restore_np(pthread_mutex_unlock, (void *) &mut);
	      /* do some work */

					   LinuxThreads 		       PTHREAD_CLEANUP(3)
Unix & Linux Commands & Man Pages : ©2000 - 2018 Unix and Linux Forums

All times are GMT -4. The time now is 05:33 AM.