fix subprocess issues
Fix SIGCHLD suspension for fork()-based file locks (i.e., Solaris).
Also, fix commit ea51d32e
, which broke termination of process groups
where the main process terminated before the rest of the group,
because it used sigwait() before the terminate action.
This commit is contained in:
parent
d93ce089a3
commit
3ca82d5df7
|
@ -753,7 +753,7 @@ static void add_child_status(int pid, int status) {
|
|||
if (st->signal_fd)
|
||||
scheme_signal_received_at(st->signal_fd);
|
||||
if (st->unneeded)
|
||||
(void)scheme_get_child_status(st->pid, 0, NULL);
|
||||
(void)scheme_get_child_status(st->pid, 0, 0, NULL);
|
||||
}
|
||||
|
||||
static int raw_get_child_status(int pid, int *status, int done_only, int do_remove, int do_free) {
|
||||
|
@ -782,12 +782,12 @@ static int raw_get_child_status(int pid, int *status, int done_only, int do_remo
|
|||
return found;
|
||||
}
|
||||
|
||||
int scheme_get_child_status(int pid, int is_group, int *status) {
|
||||
int scheme_get_child_status(int pid, int is_group, int can_check_group, int *status) {
|
||||
int found = 0;
|
||||
|
||||
/* Check specific pid, in case the child has its own group
|
||||
(either given by Racket or given to itself): */
|
||||
{
|
||||
if (can_check_group) {
|
||||
pid_t pid2;
|
||||
int status;
|
||||
|
||||
|
|
|
@ -8528,6 +8528,30 @@ int scheme_os_pipe(intptr_t *a, int nearh)
|
|||
|
||||
/**************** Unix: signal stuff ******************/
|
||||
|
||||
#if defined(UNIX_PROCESSES)
|
||||
|
||||
void scheme_block_child_signals(int block)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
#if defined(MZ_PLACES_WAITPID)
|
||||
if (block)
|
||||
scheme_wait_suspend();
|
||||
else
|
||||
scheme_wait_resume();
|
||||
#else
|
||||
sigset_t sigs;
|
||||
|
||||
sigemptyset(&sigs);
|
||||
sigaddset(&sigs, SIGCHLD);
|
||||
# ifdef USE_ITIMER
|
||||
sigaddset(&sigs, SIGPROF);
|
||||
# endif
|
||||
sigprocmask(block ? SIG_BLOCK : SIG_UNBLOCK, &sigs, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(UNIX_PROCESSES) && !defined(MZ_PLACES_WAITPID)
|
||||
|
||||
#ifndef MZ_PRECISE_GC
|
||||
|
@ -8541,21 +8565,6 @@ SHARED_OK static void *unused_pids;
|
|||
|
||||
static int need_to_check_children;
|
||||
|
||||
void scheme_block_child_signals(int block)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
#if !defined(MZ_PLACES_WAITPID)
|
||||
sigset_t sigs;
|
||||
|
||||
sigemptyset(&sigs);
|
||||
sigaddset(&sigs, SIGCHLD);
|
||||
# ifdef USE_ITIMER
|
||||
sigaddset(&sigs, SIGPROF);
|
||||
# endif
|
||||
sigprocmask(block ? SIG_BLOCK : SIG_UNBLOCK, &sigs, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void child_done(int ingored)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
|
@ -9012,7 +9021,7 @@ static int subp_done(Scheme_Object *so)
|
|||
{
|
||||
int status;
|
||||
if (!sp->done) {
|
||||
if (scheme_get_child_status(sp->pid, sp->is_group, &status)) {
|
||||
if (scheme_get_child_status(sp->pid, sp->is_group, 1, &status)) {
|
||||
sp->done = 1;
|
||||
sp->status = status;
|
||||
child_mref_done(sp);
|
||||
|
@ -9078,7 +9087,7 @@ static Scheme_Object *subprocess_status(int argc, Scheme_Object **argv)
|
|||
if (sp->done)
|
||||
status = sp->status;
|
||||
else {
|
||||
if (!scheme_get_child_status(sp->pid, sp->is_group, &status)) {
|
||||
if (!scheme_get_child_status(sp->pid, sp->is_group, 1, &status)) {
|
||||
going = 1;
|
||||
} else {
|
||||
child_mref_done(sp);
|
||||
|
@ -9167,9 +9176,9 @@ static Scheme_Object *do_subprocess_kill(Scheme_Object *_sp, Scheme_Object *kill
|
|||
|
||||
scheme_wait_suspend();
|
||||
|
||||
/* Don't pass sp->is_group, because we don't want to wait
|
||||
/* Don't allow group checking, because we don't want to wait
|
||||
on a group if we haven't already: */
|
||||
if (scheme_get_child_status(sp->pid, 0, &status)) {
|
||||
if (scheme_get_child_status(sp->pid, 0, 0, &status)) {
|
||||
sp->status = status;
|
||||
sp->done = 1;
|
||||
child_mref_done(sp);
|
||||
|
|
|
@ -4047,7 +4047,7 @@ void scheme_spawn_master_place();
|
|||
void scheme_places_block_child_signal();
|
||||
void scheme_places_unblock_child_signal();
|
||||
void scheme_places_start_child_signal_handler();
|
||||
int scheme_get_child_status(int pid, int is_group, int *status);
|
||||
int scheme_get_child_status(int pid, int is_group, int can_check_group, int *status);
|
||||
int scheme_places_register_child(int pid, int is_group, void *signal_fd, int *status);
|
||||
void scheme_wait_suspend();
|
||||
void scheme_wait_resume();
|
||||
|
|
Loading…
Reference in New Issue
Block a user