-#ifdef __pthread_unwind_next
-#undef __pthread_unwind_next
-#define __pthread_unwind_next __pthread_unwind_next_3
-#endif
-
-void __pthread_unwind_next(struct __ptcb *cb)
-{
- int i, j, not_finished;
- pthread_t self;
-
- if (cb->__next) longjmp((void *)cb->__next->__jb, 1);
-
- self = pthread_self();
- if (self->cancel) self->result = PTHREAD_CANCELLED;
-
- LOCK(&self->exitlock);
-
- not_finished = self->tsd_used;
- for (j=0; not_finished && j<PTHREAD_DESTRUCTOR_ITERATIONS; j++) {
- not_finished = 0;
- for (i=0; i<PTHREAD_KEYS_MAX; i++) {
- if (self->tsd[i] && libc.tsd_keys[i]) {
- void *tmp = self->tsd[i];
- self->tsd[i] = 0;
- libc.tsd_keys[i](tmp);
- not_finished = 1;
- }
- }
- }
-
- /* Mark this thread dead before decrementing count */
- self->dead = 1;
-
- if (!a_fetch_add(&libc.threads_minus_1, -1))
- exit(0);
-
- if (self->detached && self->map_base) {
- syscall(__NR_rt_sigprocmask, SIG_BLOCK, (long)(uint64_t[1]){-1},0,8);
- __unmapself(self->map_base, self->map_size);
- }
-
- syscall(SYS_exit, 0);
-}
-
-static void docancel(struct pthread *self)
-{
- struct __ptcb cb = { .__next = self->cancelbuf };
- sigset_t set;
- self->canceldisable = 1;
- self->cancelasync = 0;
- sigemptyset(&set);
- sigaddset(&set, SIGCANCEL);
- __libc_sigprocmask(SIG_UNBLOCK, &set, 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 > 0 || si->si_pid != self->pid) return;
- self->cancel = 1;
- if (self->canceldisable) return;
- if (self->cancelasync || (self->cancelpoint==1 && PC_AT_SYS(ctx)))
- docancel(self);
-}
-
-static void cancelpt(int x)