Changeset View
Changeset View
Standalone View
Standalone View
lib/libthr/thread/thr_fork.c
Show First 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | __pthread_cxa_finalize(struct dl_phdr_info *phdr_info) | ||||
while ((af = TAILQ_FIRST(&temp_list)) != NULL) { | while ((af = TAILQ_FIRST(&temp_list)) != NULL) { | ||||
TAILQ_REMOVE(&temp_list, af, qe); | TAILQ_REMOVE(&temp_list, af, qe); | ||||
free(af); | free(af); | ||||
} | } | ||||
_thr_tsd_unload(phdr_info); | _thr_tsd_unload(phdr_info); | ||||
_thr_sigact_unload(phdr_info); | _thr_sigact_unload(phdr_info); | ||||
} | } | ||||
__weak_reference(__thr_fork, _fork); | enum thr_fork_mode { | ||||
MODE_FORK, | |||||
MODE_PDFORK, | |||||
}; | |||||
pid_t | struct thr_fork_args { | ||||
__thr_fork(void) | enum thr_fork_mode mode; | ||||
void *fdp; | |||||
int flags; | |||||
}; | |||||
static pid_t | |||||
thr_fork_impl(const struct thr_fork_args *a) | |||||
{ | { | ||||
struct pthread *curthread; | struct pthread *curthread; | ||||
struct pthread_atfork *af; | struct pthread_atfork *af; | ||||
pid_t ret; | pid_t ret; | ||||
int errsave, cancelsave; | int errsave, cancelsave; | ||||
int was_threaded; | int was_threaded; | ||||
int rtld_locks[MAX_RTLD_LOCKS]; | int rtld_locks[MAX_RTLD_LOCKS]; | ||||
if (!_thr_is_inited()) | if (!_thr_is_inited()) { | ||||
switch (a->mode) { | |||||
case MODE_FORK: | |||||
return (__sys_fork()); | return (__sys_fork()); | ||||
case MODE_PDFORK: | |||||
return (__sys_pdfork(a->fdp, a->flags)); | |||||
default: | |||||
errno = EDOOFUS; | |||||
return (-1); | |||||
} | |||||
} | |||||
curthread = _get_curthread(); | curthread = _get_curthread(); | ||||
cancelsave = curthread->no_cancel; | cancelsave = curthread->no_cancel; | ||||
curthread->no_cancel = 1; | curthread->no_cancel = 1; | ||||
_thr_rwl_rdlock(&_thr_atfork_lock); | _thr_rwl_rdlock(&_thr_atfork_lock); | ||||
/* Run down atfork prepare handlers. */ | /* Run down atfork prepare handlers. */ | ||||
TAILQ_FOREACH_REVERSE(af, &_thr_atfork_list, atfork_head, qe) { | TAILQ_FOREACH_REVERSE(af, &_thr_atfork_list, atfork_head, qe) { | ||||
Show All 24 Lines | thr_fork_impl(const struct thr_fork_args *a) | ||||
/* | /* | ||||
* Fork a new process. | * Fork a new process. | ||||
* There is no easy way to pre-resolve the __sys_fork symbol | * There is no easy way to pre-resolve the __sys_fork symbol | ||||
* without performing the fork. Use the syscall(2) | * without performing the fork. Use the syscall(2) | ||||
* indirection, the syscall symbol is resolved in | * indirection, the syscall symbol is resolved in | ||||
* _thr_rtld_init() with side-effect free call. | * _thr_rtld_init() with side-effect free call. | ||||
*/ | */ | ||||
switch (a->mode) { | |||||
case MODE_FORK: | |||||
ret = syscall(SYS_fork); | ret = syscall(SYS_fork); | ||||
break; | |||||
case MODE_PDFORK: | |||||
ret = syscall(SYS_pdfork, a->fdp, a->flags); | |||||
break; | |||||
default: | |||||
ret = -1; | |||||
errno = EDOOFUS; | |||||
break; | |||||
markj: We should just return -1 here I think. | |||||
Done Inline ActionsWe need to undo everything we did to prepare for fork. This is mostly theoretical, of course. kib: We need to undo everything we did to prepare for fork. This is mostly theoretical, of course. | |||||
} | |||||
if (ret == 0) { | if (ret == 0) { | ||||
/* Child process */ | /* Child process */ | ||||
errsave = errno; | errsave = errno; | ||||
curthread->cancel_pending = 0; | curthread->cancel_pending = 0; | ||||
curthread->flags &= ~(THR_FLAGS_NEED_SUSPEND|THR_FLAGS_DETACHED); | curthread->flags &= ~(THR_FLAGS_NEED_SUSPEND|THR_FLAGS_DETACHED); | ||||
/* | /* | ||||
* Thread list will be reinitialized, and later we call | * Thread list will be reinitialized, and later we call | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | if (ret == 0) { | ||||
curthread->no_cancel = cancelsave; | curthread->no_cancel = cancelsave; | ||||
/* test async cancel */ | /* test async cancel */ | ||||
if (curthread->cancel_async) | if (curthread->cancel_async) | ||||
_thr_testcancel(curthread); | _thr_testcancel(curthread); | ||||
} | } | ||||
errno = errsave; | errno = errsave; | ||||
return (ret); | return (ret); | ||||
} | |||||
__weak_reference(__thr_fork, _fork); | |||||
pid_t | |||||
__thr_fork(void) | |||||
{ | |||||
struct thr_fork_args a; | |||||
a.mode = MODE_FORK; | |||||
return (thr_fork_impl(&a)); | |||||
} | |||||
pid_t | |||||
__thr_pdfork(int *fdp, int flags) | |||||
{ | |||||
struct thr_fork_args a; | |||||
a.mode = MODE_PDFORK; | |||||
a.fdp = fdp; | |||||
a.flags = flags; | |||||
return (thr_fork_impl(&a)); | |||||
} | } |
We should just return -1 here I think.