123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- #include <errno.h>
- #include <signal.h>
- #include "pthreadP.h"
- #include "atomic.h"
- #include <sysdep.h>
- #include <bits/kernel-features.h>
- int
- pthread_cancel (th)
- pthread_t th;
- {
- volatile struct pthread *pd = (volatile struct pthread *) th;
-
- if (INVALID_TD_P (pd))
-
- return ESRCH;
- #ifdef SHARED
- pthread_cancel_init ();
- #endif
- int result = 0;
- int oldval;
- int newval;
- do
- {
- oldval = pd->cancelhandling;
- newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
-
- if (oldval == newval)
- break;
-
- if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
- {
-
- atomic_bit_set (&pd->cancelhandling, CANCELING_BIT);
-
- INTERNAL_SYSCALL_DECL (err);
-
- int val;
- #if __ASSUME_TGKILL
- val = INTERNAL_SYSCALL (tgkill, err, 3,
- THREAD_GETMEM (THREAD_SELF, pid), pd->tid,
- SIGCANCEL);
- #else
- # ifdef __NR_tgkill
- val = INTERNAL_SYSCALL (tgkill, err, 3,
- THREAD_GETMEM (THREAD_SELF, pid), pd->tid,
- SIGCANCEL);
- if (INTERNAL_SYSCALL_ERROR_P (val, err)
- && INTERNAL_SYSCALL_ERRNO (val, err) == ENOSYS)
- # endif
- val = INTERNAL_SYSCALL (tkill, err, 2, pd->tid, SIGCANCEL);
- #endif
- if (INTERNAL_SYSCALL_ERROR_P (val, err))
- result = INTERNAL_SYSCALL_ERRNO (val, err);
- break;
- }
- }
-
- while (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling, newval,
- oldval));
- return result;
- }
- PTHREAD_STATIC_FN_REQUIRE (pthread_create)
|