Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Blocking child signals



On Jul 15,  4:43am, Zoltan Hidvegi wrote:
} Subject: Blocking child signals
}
} In exec.c and in jobs.c there are several child_block() and child_unblock()
} calls.  Tracing the system calls used by zsh it turns out that perhaps the
} majority of these are these child block/unblock calls.  I think that the
} performance of zsh could be improved a little bit by calling these blocking
} code more carefully.

It's possible you'd get a little performance, but I don't think it's
worth the effort.  Signal blocking/unblocking shouldn't be a very time-
consuming operation, except maybe for the old-style SYSV_SIGNALS or no-
signal-blocking cases.

I'd be willing to bet that the vast majority of those block/unblock pairs
are happening in waitjob() and relatives, where zsh is in a loop doing
almost nothing else.  You're not going to get any useful performance out
of speeding that up, because at that point zsh is bound by the execution
of one or more child processes.

} Unfortunately this child blocking stuff is quite a
} mess.  I'm sure that there are some bugs hiding here (ie. the child signal
} may remain blocked sometimes for quite a long time or it may be unblocked
} when it should not be unblocked).

I'm just scanning through it ... there's a bug on line 602 of exec.c,
where if initjob() fails zsh returns without unblocking the signals.

Otherwise it looks as though all the blocks are correctly matched
with unblocks; it's just a little hard to follow because in some cases
the block happens in a subroutine [e.g. down in execcmd()] and the
unblock doesn't happen until after returning from a couple of levels
deep of nested call [e.g. in execpline()].

There certainly isn't anyplace in jobs.c where the the calls are not
matched, nor is there anywhere in jobs.c where the signal could be
blocked for less time.  Part of the reason exec.c is so difficult to
follow is because of delaying the block until the last possible moment;
that makes it impossible to set up syntactically matched pairs as we
did with the allocation routines.

} I think that zsh should not block child signals when it does not fork.  Is
} there anyone who knows the details of this child blocking staff in exec.c?

Most of it actually originated with me, although it got heavily modified
by someone (RC?) to take better advantage of the POSIX signal stuff.  It
was also during my hiatus from the list that most of the block calls got
pushed farther down the subroutine stack to limit the duration of signal
blocking.  Peter may recall something about that.

It's important to block SIGCHLD signals not just before forking, but at
any time you're going to manipulate the job table if any child is still
executing.  You could add code to examine the job table and avoid making
the system call when no children exist, but my guess is that would be
just as expensive as simply making the call.

The child blocking stuff corrected a whole bunch of zsh bugs, including
(if I recall correctly) one where pipelines like "/bin/echo foo | less",
where the first command exits very quickly, confused zsh into thinking
the entire pipeline had exited, thus leaving "less" an orphan.

-- 
Bart Schaefer                             Brass Lantern Enterprises
http://www.well.com/user/barts            http://www.nbn.com/people/lantern

New male in /home/schaefer:
>N  2 Justin William Schaefer  Sat May 11 03:43  53/4040  "Happy Birthday"




Messages sorted by: Reverse Date, Date, Thread, Author