X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fthread%2Fpthread_cancel.c;h=2f9d5e975f22ca60e7e9baca84b97bb6378fccac;hb=69a1b39019c51258af14c0b2d836c23d20929c9a;hp=6eaf72c45c90e82b9e4bbe5bc2314111d39bc977;hpb=cb1bf2f321b45a06447133b3db00621b7300c456;p=musl diff --git a/src/thread/pthread_cancel.c b/src/thread/pthread_cancel.c index 6eaf72c4..2f9d5e97 100644 --- a/src/thread/pthread_cancel.c +++ b/src/thread/pthread_cancel.c @@ -2,12 +2,8 @@ #include #include "pthread_impl.h" #include "syscall.h" -#include "libc.h" -#ifdef SHARED -__attribute__((__visibility__("hidden"))) -#endif -long __cancel(), __cp_cancel(), __syscall_cp_asm(), __syscall_cp_c(); +hidden long __cancel(), __syscall_cp_asm(), __syscall_cp_c(); long __cancel() { @@ -18,12 +14,6 @@ long __cancel() return -ECANCELED; } -/* If __syscall_cp_asm has adjusted the stack pointer, it must provide a - * definition of __cp_cancel to undo those adjustments and call __cancel. - * Otherwise, __cancel provides a definition for __cp_cancel. */ - -weak_alias(__cancel, __cp_cancel); - long __syscall_cp_asm(volatile void *, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t); @@ -53,10 +43,7 @@ static void _sigaddset(sigset_t *set, int sig) set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1); } -#ifdef SHARED -__attribute__((__visibility__("hidden"))) -#endif -extern const char __cp_begin[1], __cp_end[1]; +extern hidden const char __cp_begin[1], __cp_end[1], __cp_cancel[1]; static void cancel_handler(int sig, siginfo_t *si, void *ctx) { @@ -71,6 +58,9 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx) if (self->cancelasync || pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) { uc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel; +#ifdef CANCEL_GOT + uc->uc_mcontext.MC_GOT = CANCEL_GOT; +#endif return; } @@ -102,5 +92,10 @@ int pthread_cancel(pthread_t t) init = 1; } a_store(&t->cancel, 1); + if (t == pthread_self()) { + if (t->canceldisable == PTHREAD_CANCEL_ENABLE && t->cancelasync) + pthread_exit(PTHREAD_CANCELED); + return 0; + } return pthread_kill(t, SIGCANCEL); }