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)
|
if (st->signal_fd)
|
||||||
scheme_signal_received_at(st->signal_fd);
|
scheme_signal_received_at(st->signal_fd);
|
||||||
if (st->unneeded)
|
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) {
|
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;
|
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;
|
int found = 0;
|
||||||
|
|
||||||
/* Check specific pid, in case the child has its own group
|
/* Check specific pid, in case the child has its own group
|
||||||
(either given by Racket or given to itself): */
|
(either given by Racket or given to itself): */
|
||||||
{
|
if (can_check_group) {
|
||||||
pid_t pid2;
|
pid_t pid2;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
|
|
@ -8528,6 +8528,30 @@ int scheme_os_pipe(intptr_t *a, int nearh)
|
||||||
|
|
||||||
/**************** Unix: signal stuff ******************/
|
/**************** 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)
|
#if defined(UNIX_PROCESSES) && !defined(MZ_PLACES_WAITPID)
|
||||||
|
|
||||||
#ifndef MZ_PRECISE_GC
|
#ifndef MZ_PRECISE_GC
|
||||||
|
@ -8541,21 +8565,6 @@ SHARED_OK static void *unused_pids;
|
||||||
|
|
||||||
static int need_to_check_children;
|
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)
|
static void child_done(int ingored)
|
||||||
XFORM_SKIP_PROC
|
XFORM_SKIP_PROC
|
||||||
{
|
{
|
||||||
|
@ -9012,7 +9021,7 @@ static int subp_done(Scheme_Object *so)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
if (!sp->done) {
|
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->done = 1;
|
||||||
sp->status = status;
|
sp->status = status;
|
||||||
child_mref_done(sp);
|
child_mref_done(sp);
|
||||||
|
@ -9078,7 +9087,7 @@ static Scheme_Object *subprocess_status(int argc, Scheme_Object **argv)
|
||||||
if (sp->done)
|
if (sp->done)
|
||||||
status = sp->status;
|
status = sp->status;
|
||||||
else {
|
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;
|
going = 1;
|
||||||
} else {
|
} else {
|
||||||
child_mref_done(sp);
|
child_mref_done(sp);
|
||||||
|
@ -9167,9 +9176,9 @@ static Scheme_Object *do_subprocess_kill(Scheme_Object *_sp, Scheme_Object *kill
|
||||||
|
|
||||||
scheme_wait_suspend();
|
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: */
|
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->status = status;
|
||||||
sp->done = 1;
|
sp->done = 1;
|
||||||
child_mref_done(sp);
|
child_mref_done(sp);
|
||||||
|
|
|
@ -4047,7 +4047,7 @@ void scheme_spawn_master_place();
|
||||||
void scheme_places_block_child_signal();
|
void scheme_places_block_child_signal();
|
||||||
void scheme_places_unblock_child_signal();
|
void scheme_places_unblock_child_signal();
|
||||||
void scheme_places_start_child_signal_handler();
|
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);
|
int scheme_places_register_child(int pid, int is_group, void *signal_fd, int *status);
|
||||||
void scheme_wait_suspend();
|
void scheme_wait_suspend();
|
||||||
void scheme_wait_resume();
|
void scheme_wait_resume();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user