X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fthread%2Fpthread_create.c;h=52487001484ce8c1edfc08cd7b7027055c4a130d;hb=729cb49f52c825ac44f437e1ff0865d9f0b3626a;hp=344b39f8d2031694132d88142f0a1786b8b401bc;hpb=1ad049b7b60b2c1704b8bb5b94ee4f95d7540b3a;p=musl diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index 344b39f8..52487001 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -57,9 +57,19 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx) 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 @@ -85,7 +95,7 @@ static void rsyscall_handler(int sig, siginfo_t *si, void *ctx) /* Threads which have already decremented themselves from the * thread count must not increment rs.cnt or otherwise act. */ if (self->dead) { - sigaddset(&((ucontext_t *)ctx)->uc_sigmask, SIGSYSCALL); + sigfillset(&((ucontext_t *)ctx)->uc_sigmask); return; } @@ -151,13 +161,18 @@ static void init_threads() 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) @@ -190,7 +205,7 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo 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;