|
Syntax #include <pthread.h> void pthread_cleanup_push(void (*routine)(void *), void *arg); Threadsafe: Yes Signal Safe: No |
The pthread_cleanup_push() function pushes a cancelation cleanup routine onto the calling threads cancelation cleanup stack. When the thread calls pthread_exit() or is canceled via pthread_cancel(), the cancelation cleanup handlers are invoked with the argument arg.
The cancelation cleanup handlers are also invoked when they are removed from the cancelation cleanup stack via a call to pthread_cleanup_pop() and a non-zero execute argument was specified.
The pthread_cleanup_push() and the matching pthread_cleanup_pop() call should be in the same lexical scope (i.e. same level of brackets {})
When the thread calls pthread_exit() or is canceled via pthread_cancel(), the cancelation cleanup handlers are invoked with the argument specified via the pthread_cleanup_push() call that the handler was registered with.
During this thread cancelation cleanup processing, the thread invokes cancelation cleanup handlers with cancelation disabled until the last cancelation cleanup handler returns. The handlers are invoked in LIFO (Last In, First Out) order. Automatic storage for the invocation stack frame of the function that registered the handler will still be present when the cancelation cleanup handler is executed.
When a cancelation cleanup handler is invoked because of a call to pthread_cleanup_pop(1), the cancelation cleanup handler does not necessarily run with cancelation disabled. The cancelation state and cancelation type is not changed by a call to pthread_cleanup_pop(1).
A cancelation cleanup handler should not exit via longjmp() or siglongjmp(). If a cleanup handler takes an exception, the exception condition is handled and ignored and processing continues. You can look in the job log of the job to see exception messages generated by cancelation cleanup handlers.
None.
None.
#define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
#include "check.h"
void cleanupHandler(void *arg)
{
printf("In the cleanup handler\n");
}
void *threadfunc(void *parm)
{
printf("Entered secondary thread\n");
pthread_cleanup_push(cleanupHandler, NULL);
while (1) {
pthread_testcancel();
sleep(1);
}
pthread_cleanup_pop(0);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t thread;
int rc=0;
printf("Enter Testcase - %s\n", argv[0]);
/* Create a thread using default attributes */
printf("Create thread using the NULL attributes\n");
rc = pthread_create(&thread, NULL, threadfunc, NULL);
checkResults("pthread_create(NULL)\n", rc);
/* sleep() isn't a very robust way to wait for the thread */
sleep(2);
printf("Cancel the thread\n");
rc = pthread_cancel(thread);
checkResults("pthread_cancel()\n", rc);
/* sleep() isn't a very robust way to wait for the thread */
sleep(3);
printf("Main completed\n");
return 0;
}
Output
Enter Testcase - QP0WTEST/TPCLPU0 Create thread using the NULL attributes Entered secondary thread Cancel the thread In the cleanup handler Main completed