|
Syntax #include <pthread.h> int pthread_clear_exit_np(void); Threadsafe: Yes Signal Safe: Yes |
The pthread_clear_exit_np() function clears the exit status of the thread. If the thread is currently exiting due to a call to pthread_exit(), or the target of a pthread_cancel(), pthread_clear_exit_np() can be used in conjunction with setjmp(), longjmp(), andpthread_setcancelstate() to prevent a thread from terminating, and `handle' the exit condition.
The only supported way to prevent thread exit during the condition that pthread_exit() was called, or action is being taken for the target of a pthread_cancel() is shown in the example. It consists of using longjmp() from a cancelation cleanup handler, back into some thread routine that is still on the invocation stack. From that routine, the functions pthread_clear_exit_np(), and pthread_setcancelstate() are used to restore the state of the thread prior to the condition that was causing the thread exit.
This function is not portable
None.
None.
If pthread_clear_exit_np() was not successful, the error condition returned usually indicates one of the following errors. Under some conditions, the value returned could indicate an error other than those listed here.
#define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
#include <except.h>
#include <setjmp.h>
#include "check.h"
int threadStatus=1;
void cleanupHandler(void *p)
{
jmp_buf *j = (jmp_buf *)p;
/* Warning, its quite possible that using combinations of */
/* setjmp(), longjmp(), pthread_clear_exit_np(), and */
/* pthread_setcancelstate() to handle thread exits or */
/* cancelation could result in looping or non-cancelable */
/* threads if done incorrectly. */
printf("In cancelation cleanup handler. Handling the thread exit\n");
longjmp(*j, 1);
printf("The exit/cancelation wasn't stopped!\n");
return;
}
void *threadfunc(void *parm)
{
jmp_buf j;
int rc, old;
printf("Inside secondary thread\n");
if (setjmp(j)) {
/* Returned from longjmp after stopping the thread exit */
/* Since longjmp was called from within the cancelation */
/* cleanup handler, we must clear the exit state of the */
/* thread and reset the cancelability state to what it was */
/* before the cancelation cleanup handlers were invoked */
/* (Cancelation cleanup handlers are invoked with */
/* thread cancelation disabled) */
printf("Stopped the thread exit, now clean up the states\n");
printf("Clear exit state\n");
rc = pthread_clear_exit_np();
checkResults("pthread_clear_exit_np()\n", rc);
printf("Restore cancel state\n");
rc = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
checkResults("pthread_setcancelstate()\n", rc);
/* This example was successful */
threadStatus = 0;
}
else {
printf("Pushing cleanup handler that will stop the exit\n");
pthread_cleanup_push(cleanupHandler, &j);
/* This exit will be stopped by cleanupHandler2 and the */
/* pthread_clear_exit_np() that is done above */
pthread_exit(__VOID(threadStatus));
printf("Didn't expect to get here! Left status as 1.\n");
pthread_cleanup_pop(0);
}
pthread_exit(__VOID(threadStatus));
}
int main(int argc, char **argv)
{
pthread_t thread;
int rc=0;
char c;
void *status;
printf("Enter Testcase - %s\n", argv[0]);
printf("Create thread that will demonstrate handling an exit\n");
rc = pthread_create(&thread, NULL, threadfunc, NULL);
checkResults("pthread_create()\n", rc);
rc = pthread_join(thread, &status);
checkResults("pthread_join()\n", rc);
if (__INT(status) != 0) {
printf("Got an unexpected return status from the thread!\n");
exit(1);
}
printf("Main completed\n");
return 0;
}
Output
Enter Testcase - QP0WTEST/TPCEXIT0 Create thread that will demonstrate handling an exit Inside secondary thread Pushing cleanup handler that will stop the exit In cancelation cleanup handler. Handling the thread exit Stopped the thread exit, now clean up the states Clear exit state Restore cancel state Main completed