|
Syntax #include <pthread.h> int pthread_setcanceltype(int type, int *oldtype); Threadsafe: Yes Signal Safe: Yes |
The pthread_setcanceltype() function sets the cancel type to one of PTHREAD_CANCEL_DEFERRED or PTHREAD_CANCEL_ASYNCHRONOUS and returns the old cancel type into the location specified by oldtype (if oldtype is non-NULL)
Cancelability consists of 3 separate states (disabled, deferred, asynchronous) that can be represented by 2 boolean values.
| Cancelability | Cancelability State | Cancelability Type |
|---|---|---|
| disabled | PTHREAD_CANCEL_DISABLE | PTHREAD_CANCEL_DEFERRED |
| disabled | PTHREAD_CANCEL_DISABLE | PTHREAD_CANCEL_ASYNCHRONOUS |
| deferred | PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED |
| asynchronous | PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_ASYNCHRONOUS |
The default cancelability state is deferred.
When cancelability is disabled, all cancels are held pending in the target thread until the thread changes the cancelability. When cancelability is deferred, all cancels are held pending in the target thread until the thread changes the cancelability, calls a function which is a cancelation point or calls pthread_testcancel(), thus creating a cancelation point. When cancelability is asynchronous, all cancels are acted upon immediately, interrupting the thread with its processing.
It is recommended that your application not use asynchronous thread cancelation via the PTHREAD_CANCEL_ASYNCHRONOUS option of pthread_setcanceltype(). See the common user errors section of this document for more information.
None.
If pthread_setcanceltype() 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 "check.h"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void cleanupHandler(void *parm)
{
int rc;
printf("Inside cleanup handler, unlock mutex\n");
rc = pthread_mutex_unlock((pthread_mutex_t *)parm);
checkResults("pthread_mutex_unlock\n", rc);
}
void *threadfunc(void *parm)
{
int rc;
int oldtype;
printf("Entered secondary thread, lock mutex\n");
rc = pthread_mutex_lock(&mutex);
checkResults("pthread_mutex_lock()\n", rc);
pthread_cleanup_push(cleanupHandler, &mutex);
/* We must assume there's a good reason for async. cancellability */
/* and also, we must assume that if we get interrupted, its */
/* appropriate to unlock the mutex. More than likely it isn't */
/* because we'll have left some data structures in a strange state */
/* if we're async. interrupted while holding the mutex */
rc = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
checkResults("pthread_setcanceltype()\n", rc);
printf("Secondary thread is now looping\n");
while (1) { sleep(1); }
printf("Unexpectedly got out of loop!\n");
pthread_cleanup_pop(0);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t thread;
int rc=0;
void *status;
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(1);
printf("Cancel the thread\n");
rc = pthread_cancel(thread);
checkResults("pthread_cancel()\n", rc);
rc = pthread_join(thread, &status);
if (status != PTHREAD_CANCELED) {
printf("Unexpected thread status\n");
exit(1);
}
printf("Main completed\n");
return 0;
}
Output
Enter Testcase - QP0WTEST/TPSETCANT0 Create thread using the NULL attributes Entered secondary thread, lock mutex Secondary thread is now looping Cancel the thread Inside cleanup handler, unlock mutex Main completed