static void cancelpt(int x)
{
struct pthread *self = __pthread_self();
- if (self->canceldisable) return;
- if ((self->cancelpoint+=x)==1 && x>=0 && self->cancel)
- docancel(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;
+ }
}
/* "rsyscall" is a mechanism by which a thread can synchronously force all
/* Threads which have already decremented themselves from the
* thread count must not increment rs.cnt or otherwise act. */
if (self->dead) {
- __wait(&rs.hold, 0, 1, 1);
+ sigfillset(&((ucontext_t *)ctx)->uc_sigmask);
return;
}
libc.lockfile = __lockfile;
libc.cancelpt = cancelpt;
libc.rsyscall = rsyscall;
+
+ sigfillset(&sa.sa_mask);
+ sa.sa_sigaction = rsyscall_handler;
+ __libc_sigaction(SIGSYSCALL, &sa, 0);
+
+ sigemptyset(&sa.sa_mask);
sa.sa_sigaction = cancel_handler;
__libc_sigaction(SIGCANCEL, &sa, 0);
+
sigaddset(&sa.sa_mask, SIGSYSCALL);
sigaddset(&sa.sa_mask, SIGCANCEL);
- sa.sa_sigaction = rsyscall_handler;
- __libc_sigaction(SIGSYSCALL, &sa, 0);
- sigprocmask(SIG_UNBLOCK, &sa.sa_mask, 0);
+ __libc_sigprocmask(SIG_UNBLOCK, &sa.sa_mask, 0);
}
static int start(void *p)
unsigned char *map, *stack, *tsd;
static const pthread_attr_t default_attr;
- if (!self) return errno = ENOSYS;
+ if (!self) return ENOSYS;
if (!init && ++init) init_threads();
if (!attr) attr = &default_attr;