summaryrefslogtreecommitdiffstats
path: root/man/man3/pthread_cleanup_push.3
diff options
context:
space:
mode:
Diffstat (limited to 'man/man3/pthread_cleanup_push.3')
-rw-r--r--man/man3/pthread_cleanup_push.3319
1 files changed, 319 insertions, 0 deletions
diff --git a/man/man3/pthread_cleanup_push.3 b/man/man3/pthread_cleanup_push.3
new file mode 100644
index 000000000..7026929a8
--- /dev/null
+++ b/man/man3/pthread_cleanup_push.3
@@ -0,0 +1,319 @@
+'\" t
+.\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
+.\" <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH pthread_cleanup_push 3 (date) "Linux man-pages (unreleased)"
+.SH NAME
+pthread_cleanup_push, pthread_cleanup_pop \- push and pop
+thread cancelation clean-up handlers
+.SH LIBRARY
+POSIX threads library
+.RI ( libpthread ", " \-lpthread )
+.SH SYNOPSIS
+.nf
+.B #include <pthread.h>
+.P
+.BI "void pthread_cleanup_push(void (*" routine ")(void *), void *" arg );
+.BI "void pthread_cleanup_pop(int " execute );
+.fi
+.SH DESCRIPTION
+These functions manipulate the calling thread's stack of
+thread-cancelation clean-up handlers.
+A clean-up handler is a function that is automatically executed
+when a thread is canceled (or in various other circumstances
+described below);
+it might, for example, unlock a mutex so that
+it becomes available to other threads in the process.
+.P
+The
+.BR pthread_cleanup_push ()
+function pushes
+.I routine
+onto the top of the stack of clean-up handlers.
+When
+.I routine
+is later invoked, it will be given
+.I arg
+as its argument.
+.P
+The
+.BR pthread_cleanup_pop ()
+function removes the routine at the top of the stack of clean-up handlers,
+and optionally executes it if
+.I execute
+is nonzero.
+.P
+A cancelation clean-up handler is popped from the stack
+and executed in the following circumstances:
+.IP \[bu] 3
+When a thread is canceled,
+all of the stacked clean-up handlers are popped and executed in
+the reverse of the order in which they were pushed onto the stack.
+.IP \[bu]
+When a thread terminates by calling
+.BR pthread_exit (3),
+all clean-up handlers are executed as described in the preceding point.
+(Clean-up handlers are
+.I not
+called if the thread terminates by
+performing a
+.I return
+from the thread start function.)
+.IP \[bu]
+When a thread calls
+.BR pthread_cleanup_pop ()
+with a nonzero
+.I execute
+argument, the top-most clean-up handler is popped and executed.
+.P
+POSIX.1 permits
+.BR pthread_cleanup_push ()
+and
+.BR pthread_cleanup_pop ()
+to be implemented as macros that expand to text
+containing \[aq]\fB{\fP\[aq] and \[aq]\fB}\fP\[aq], respectively.
+For this reason, the caller must ensure that calls to these
+functions are paired within the same function,
+and at the same lexical nesting level.
+(In other words, a clean-up handler is established only
+during the execution of a specified section of code.)
+.P
+Calling
+.BR longjmp (3)
+.RB ( siglongjmp (3))
+produces undefined results if any call has been made to
+.BR pthread_cleanup_push ()
+or
+.BR pthread_cleanup_pop ()
+without the matching call of the pair since the jump buffer
+was filled by
+.BR setjmp (3)
+.RB ( sigsetjmp (3)).
+Likewise, calling
+.BR longjmp (3)
+.RB ( siglongjmp (3))
+from inside a clean-up handler produces undefined results
+unless the jump buffer was also filled by
+.BR setjmp (3)
+.RB ( sigsetjmp (3))
+inside the handler.
+.SH RETURN VALUE
+These functions do not return a value.
+.SH ERRORS
+There are no errors.
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lbx lb lb
+l l l.
+Interface Attribute Value
+T{
+.na
+.nh
+.BR pthread_cleanup_push (),
+.BR pthread_cleanup_pop ()
+T} Thread safety MT-Safe
+.TE
+.SH VERSIONS
+On glibc, the
+.BR pthread_cleanup_push ()
+and
+.BR pthread_cleanup_pop ()
+functions
+.I are
+implemented as macros that expand to text
+containing \[aq]\fB{\fP\[aq] and \[aq]\fB}\fP\[aq], respectively.
+This means that variables declared within the scope of
+paired calls to these functions will be visible within only that scope.
+.P
+POSIX.1
+.\" The text was actually added in the 2004 TC2
+says that the effect of using
+.IR return ,
+.IR break ,
+.IR continue ,
+or
+.I goto
+to prematurely leave a block bracketed
+.BR pthread_cleanup_push ()
+and
+.BR pthread_cleanup_pop ()
+is undefined.
+Portable applications should avoid doing this.
+.SH STANDARDS
+POSIX.1-2008.
+.SH HISTORY
+POSIX.1-2001.
+glibc 2.0.
+.SH EXAMPLES
+The program below provides a simple example of the use of the functions
+described in this page.
+The program creates a thread that executes a loop bracketed by
+.BR pthread_cleanup_push ()
+and
+.BR pthread_cleanup_pop ().
+This loop increments a global variable,
+.IR cnt ,
+once each second.
+Depending on what command-line arguments are supplied,
+the main thread sends the other thread a cancelation request,
+or sets a global variable that causes the other thread
+to exit its loop and terminate normally (by doing a
+.IR return ).
+.P
+In the following shell session,
+the main thread sends a cancelation request to the other thread:
+.P
+.in +4n
+.EX
+$ \fB./a.out\fP
+New thread started
+cnt = 0
+cnt = 1
+Canceling thread
+Called clean\-up handler
+Thread was canceled; cnt = 0
+.EE
+.in
+.P
+From the above, we see that the thread was canceled,
+and that the cancelation clean-up handler was called
+and it reset the value of the global variable
+.I cnt
+to 0.
+.P
+In the next run, the main program sets a
+global variable that causes other thread to terminate normally:
+.P
+.in +4n
+.EX
+$ \fB./a.out x\fP
+New thread started
+cnt = 0
+cnt = 1
+Thread terminated normally; cnt = 2
+.EE
+.in
+.P
+From the above, we see that the clean-up handler was not executed (because
+.I cleanup_pop_arg
+was 0), and therefore the value of
+.I cnt
+was not reset.
+.P
+In the next run, the main program sets a global variable that
+causes the other thread to terminate normally,
+and supplies a nonzero value for
+.IR cleanup_pop_arg :
+.P
+.in +4n
+.EX
+$ \fB./a.out x 1\fP
+New thread started
+cnt = 0
+cnt = 1
+Called clean\-up handler
+Thread terminated normally; cnt = 0
+.EE
+.in
+.P
+In the above, we see that although the thread was not canceled,
+the clean-up handler was executed, because the argument given to
+.BR pthread_cleanup_pop ()
+was nonzero.
+.SS Program source
+\&
+.\" SRC BEGIN (pthread_cleanup_push.c)
+.EX
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+\&
+#define handle_error_en(en, msg) \e
+ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
+\&
+static int done = 0;
+static int cleanup_pop_arg = 0;
+static int cnt = 0;
+\&
+static void
+cleanup_handler(void *arg)
+{
+ printf("Called clean\-up handler\en");
+ cnt = 0;
+}
+\&
+static void *
+thread_start(void *arg)
+{
+ time_t curr;
+\&
+ printf("New thread started\en");
+\&
+ pthread_cleanup_push(cleanup_handler, NULL);
+\&
+ curr = time(NULL);
+\&
+ while (!done) {
+ pthread_testcancel(); /* A cancelation point */
+ if (curr < time(NULL)) {
+ curr = time(NULL);
+ printf("cnt = %d\en", cnt); /* A cancelation point */
+ cnt++;
+ }
+ }
+\&
+ pthread_cleanup_pop(cleanup_pop_arg);
+ return NULL;
+}
+\&
+int
+main(int argc, char *argv[])
+{
+ pthread_t thr;
+ int s;
+ void *res;
+\&
+ s = pthread_create(&thr, NULL, thread_start, NULL);
+ if (s != 0)
+ handle_error_en(s, "pthread_create");
+\&
+ sleep(2); /* Allow new thread to run a while */
+\&
+ if (argc > 1) {
+ if (argc > 2)
+ cleanup_pop_arg = atoi(argv[2]);
+ done = 1;
+\&
+ } else {
+ printf("Canceling thread\en");
+ s = pthread_cancel(thr);
+ if (s != 0)
+ handle_error_en(s, "pthread_cancel");
+ }
+\&
+ s = pthread_join(thr, &res);
+ if (s != 0)
+ handle_error_en(s, "pthread_join");
+\&
+ if (res == PTHREAD_CANCELED)
+ printf("Thread was canceled; cnt = %d\en", cnt);
+ else
+ printf("Thread terminated normally; cnt = %d\en", cnt);
+ exit(EXIT_SUCCESS);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.BR pthread_cancel (3),
+.BR pthread_cleanup_push_defer_np (3),
+.BR pthread_setcancelstate (3),
+.BR pthread_testcancel (3),
+.BR pthreads (7)