123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- #include <errno.h>
- #include <signal.h>
- #include "pthreadP.h"
- #include "atomic.h"
- #include <sysdep.h>
- #include <unistd.h>
- #include <bits/kernel-features.h>
- int
- pthread_cancel (
- 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
- {
- again:
- oldval = pd->cancelhandling;
- newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
-
- if (oldval == newval)
- break;
-
- if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
- {
-
- if (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling,
- oldval | CANCELING_BITMASK,
- oldval))
- goto again;
-
- INTERNAL_SYSCALL_DECL (err);
-
- pid_t pid = getpid ();
- int val;
- val = INTERNAL_SYSCALL (tgkill, err, 3, pid, pd->tid, SIGCANCEL);
- 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)
|