1 #include "pthread_impl.h"
9 static void (*callback)(void *), *context;
11 static sem_t chainlock, chaindone;
13 static void handler(int sig, siginfo_t *si, void *ctx)
16 pthread_t self = __pthread_self();
17 int old_errno = errno;
19 if (chainlen == libc.threads_minus_1) return;
21 sigqueue(self->pid, SIGSYNCCALL, (union sigval){0});
23 sem_init(&ch.sem, 0, 0);
24 sem_init(&ch.sem2, 0, 0);
26 while (sem_wait(&chainlock));
29 if (++chainlen == libc.threads_minus_1) sem_post(&chaindone);
32 while (sem_wait(&ch.sem));
35 while (sem_wait(&ch.sem));
40 void __synccall(void (*func)(void *), void *ctx)
47 if (!libc.threads_minus_1) {
54 __block_all_sigs(&oldmask);
56 sem_init(&chaindone, 0, 0);
57 sem_init(&chainlock, 0, 1);
63 sa.sa_flags = SA_SIGINFO | SA_RESTART;
64 sa.sa_sigaction = handler;
65 sigfillset(&sa.sa_mask);
66 __libc_sigaction(SIGSYNCCALL, &sa, 0);
68 self = __pthread_self();
69 sigqueue(self->pid, SIGSYNCCALL, (union sigval){0});
70 while (sem_wait(&chaindone));
73 sa.sa_handler = SIG_IGN;
74 __libc_sigaction(SIGSYNCCALL, &sa, 0);
76 for (cur=head; cur; cur=cur->next) {
78 while (sem_wait(&cur->sem2));
82 for (cur=head; cur; cur=next) {
87 __restore_sigs(&oldmask);