В некоторых случаях pthread_setcanceltype()
действительно должен сделать отмену (см. Источник ниже). Итак, это причина, почему нет pthread_setcanceltype_for_thread()
. Фактический тип отмены - это поле в структуре pthread, которое должно быть изменено атомарно.
FTP: //sources.redhat.com/pub/glibc/snapshots/glibc-latest.tar.bz2/glibc-20090518/nptl/pthread_setcanceltype.c
__pthread_setcanceltype (type, oldtype)
int type;
int *oldtype;
{
volatile struct pthread *self;
self = THREAD_SELF;
int oldval = THREAD_GETMEM (self, cancelhandling);
while (1)
{
int newval = (type == PTHREAD_CANCEL_ASYNCHRONOUS
? oldval | CANCELTYPE_BITMASK
: oldval & ~CANCELTYPE_BITMASK);
/* Store the old value. */
if (oldtype != NULL)
*oldtype = ((oldval & CANCELTYPE_BITMASK)
? PTHREAD_CANCEL_ASYNCHRONOUS : PTHREAD_CANCEL_DEFERRED);
/* Update the cancel handling word. This has to be done
atomically since other bits could be modified as well. */
int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
oldval);
if (__builtin_expect (curval == oldval, 1))
{
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
{
THREAD_SETMEM (self, result, PTHREAD_CANCELED);
__do_cancel (); // HERE THE CANCELLING
}
break;
}
/* Prepare for the next round. */
oldval = curval;
}
return 0;
}
strong_alias (__pthread_setcanceltype, pthread_setcanceltype)
Если вам необходимо изменить тип отмены извне, вы можете взломать библиотеку и установить поле напрямую.
PS: для NPTL (текущая реализация pthreads в glibc в Linux)
Самый простой способ узнать, как получить struct pthread
из int pthread_t - это ... pthread_join:
pthread_join (pthread_t threadid, thread_return)
{
struct pthread *pd = (struct pthread *) threadid;