mirror of git://git.musl-libc.org/musl
remove everything related to forkall
i made a best attempt, but the intended semantics of this function are fundamentally contradictory. there is no consistent way to handle ownership of locks when forking a multi-threaded process. the code could have worked by accident for programs that only used normal mutexes and nothing else (since they don't actually store or care about their owner), but that's about it. broken-by-design interfaces that aren't even in glibc (only solaris) don't belong in musl.
This commit is contained in:
parent
af3330d764
commit
0c29adfe42
|
@ -168,7 +168,6 @@ char *getusershell(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _GNU_SOURCE
|
#ifdef _GNU_SOURCE
|
||||||
pid_t forkall(void);
|
|
||||||
int setresuid(uid_t, uid_t, uid_t);
|
int setresuid(uid_t, uid_t, uid_t);
|
||||||
int setresgid(gid_t, gid_t, gid_t);
|
int setresgid(gid_t, gid_t, gid_t);
|
||||||
int getresuid(uid_t *, uid_t *, uid_t *);
|
int getresuid(uid_t *, uid_t *, uid_t *);
|
||||||
|
|
|
@ -52,7 +52,6 @@ void __unlockfile(FILE *);
|
||||||
#define UNLOCK(x) (libc.threads_minus_1 ? (__unlock(x),1) : ((void)(x),1))
|
#define UNLOCK(x) (libc.threads_minus_1 ? (__unlock(x),1) : ((void)(x),1))
|
||||||
|
|
||||||
void __synccall(void (*)(void *), void *);
|
void __synccall(void (*)(void *), void *);
|
||||||
void __synccall_wait(void);
|
|
||||||
int __setxid(int, int, int, int);
|
int __setxid(int, int, int, int);
|
||||||
|
|
||||||
extern char **__environ;
|
extern char **__environ;
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
#if 0
|
|
||||||
#include "pthread_impl.h"
|
|
||||||
#include <setjmp.h>
|
|
||||||
|
|
||||||
struct thread {
|
|
||||||
struct thread *next;
|
|
||||||
pthread_t td;
|
|
||||||
jmp_buf jb;
|
|
||||||
void *tmp, *stack;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ctx {
|
|
||||||
struct thread *list;
|
|
||||||
pthread_t caller;
|
|
||||||
pid_t pid;
|
|
||||||
size_t cnt;
|
|
||||||
pthread_barrier_t barrier;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void restart_thread(pthread_t self)
|
|
||||||
{
|
|
||||||
struct thread *t = self->start_arg;
|
|
||||||
self->start_arg = t->tmp;
|
|
||||||
self->pid = getpid();
|
|
||||||
longjmp(t->jb, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void do_forkall(void *p)
|
|
||||||
{
|
|
||||||
struct ctx *c = p, *volatile cv = c;
|
|
||||||
char tmpstack[2048];
|
|
||||||
struct thread *tp, t = {
|
|
||||||
.td = __pthread_self(),
|
|
||||||
.next = c->list,
|
|
||||||
.stack = tmpstack+1024
|
|
||||||
};
|
|
||||||
|
|
||||||
if (t.td != c->caller) {
|
|
||||||
c->cnt++;
|
|
||||||
t.tmp = t.td->start_arg;
|
|
||||||
t.td->start_arg = &t;
|
|
||||||
if (setjmp(t.jb)) {
|
|
||||||
c = cv;
|
|
||||||
if (c->pid) return;
|
|
||||||
pthread_barrier_wait(&c->barrier);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
c->list = &t;
|
|
||||||
__synccall_wait();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
c->pid = syscall(SYS_fork);
|
|
||||||
if (c->pid) return;
|
|
||||||
|
|
||||||
pthread_barrier_init(&c->barrier, 0, c->cnt);
|
|
||||||
for (tp=c->list; tp; tp=tp->next)
|
|
||||||
if (__uniclone(tp->stack, restart_thread, tp->td) < 0)
|
|
||||||
_exit(127);
|
|
||||||
pthread_barrier_wait(&c->barrier);
|
|
||||||
}
|
|
||||||
|
|
||||||
pid_t forkall()
|
|
||||||
{
|
|
||||||
struct ctx c = { .caller = pthread_self() };
|
|
||||||
__synccall(do_forkall, &c);
|
|
||||||
return c.pid;
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -47,14 +47,6 @@ static void handler(int sig, siginfo_t *si, void *ctx)
|
||||||
errno = old_errno;
|
errno = old_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __synccall_wait()
|
|
||||||
{
|
|
||||||
struct chain *ch = cur;
|
|
||||||
sem_post(&ch->sem2);
|
|
||||||
while (sem_wait(&ch->sem));
|
|
||||||
sem_post(&ch->sem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __synccall(void (*func)(void *), void *ctx)
|
void __synccall(void (*func)(void *), void *ctx)
|
||||||
{
|
{
|
||||||
pthread_t self;
|
pthread_t self;
|
||||||
|
|
Loading…
Reference in New Issue