-static void docancel(struct pthread *self)
-{
- struct __ptcb cb = { .__next = self->cancelbuf };
- self->canceldisable = 1;
- self->cancelasync = 0;
- __pthread_unwind_next(&cb);
-}
-
-static void cancel_handler(int sig, siginfo_t *si, void *ctx)
-{
- struct pthread *self = __pthread_self();
- if (si->si_code == SI_TIMER) __sigtimer_handler(self);
- if (self->cancel && !self->canceldisable &&
- (self->cancelasync || (self->cancelpoint==1 && PC_AT_SYS(ctx))))
- docancel(self);
-}
-
-static void cancelpt(int x)
-{
- struct pthread *self = __pthread_self();
- switch (x) {
- case 1:
- self->cancelpoint++;
- case 0:
- if (self->cancel && self->cancelpoint==1 && !self->canceldisable)
- docancel(self);
- break;
- case -1:
- self->cancelpoint--;
- break;
- default:
- self->canceldisable += x;
- }
-}
-
-static void init_threads()
-{
- struct sigaction sa = { .sa_flags = SA_SIGINFO | SA_RESTART };
- libc.lock = __lock;
- libc.lockfile = __lockfile;
- libc.cancelpt = cancelpt;
-
- sigemptyset(&sa.sa_mask);
- sa.sa_sigaction = cancel_handler;
- __libc_sigaction(SIGCANCEL, &sa, 0);
-
- sigaddset(&sa.sa_mask, SIGSYSCALL);
- sigaddset(&sa.sa_mask, SIGCANCEL);
- __libc_sigprocmask(SIG_UNBLOCK, &sa.sa_mask, 0);
-}
-