mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-21 05:18:06 +01:00
Some changes that try to address the zombie proccesses some people seem
to have.
This commit is contained in:
@@ -78,6 +78,10 @@ extern const char * const sys_siglist[];
|
|||||||
# define SA_RESTART 0
|
# define SA_RESTART 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Just in case, for weirdo systems */
|
||||||
|
#ifndef SA_NODEFER
|
||||||
|
# define SA_NODEFER 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/****** Global Variables ******/
|
/****** Global Variables ******/
|
||||||
|
|
||||||
@@ -337,12 +341,12 @@ handleSig(int sig)
|
|||||||
|
|
||||||
if (crashAction == WMRestart) {
|
if (crashAction == WMRestart) {
|
||||||
/* we try to restart Window Maker */
|
/* we try to restart Window Maker */
|
||||||
wwarning(_("trying to restart Window Maker..."));
|
wmessage(_("trying to restart Window Maker..."));
|
||||||
Restart(NULL, False);
|
Restart(NULL, False);
|
||||||
/* fallback to alternate window manager then */
|
/* fallback to alternate window manager then */
|
||||||
}
|
}
|
||||||
|
|
||||||
wwarning(_("trying to start alternate window manager..."));
|
wmessage(_("trying to start alternate window manager..."));
|
||||||
|
|
||||||
Restart(FALLBACK_WINDOWMANAGER, False);
|
Restart(FALLBACK_WINDOWMANAGER, False);
|
||||||
Restart("fvwm", False);
|
Restart("fvwm", False);
|
||||||
@@ -377,8 +381,35 @@ buryChild(int foo)
|
|||||||
int status;
|
int status;
|
||||||
|
|
||||||
/* R.I.P. */
|
/* R.I.P. */
|
||||||
pid = waitpid(-1, &status, WNOHANG);
|
/* SIGCHLD's are blocked while we are in this signal handler, and if 2 or
|
||||||
if (pid>0) {
|
* more kids exit while we handle the exit of one child in this handler
|
||||||
|
* (ie, about at the same time), we will miss the SIGCHLD signals the
|
||||||
|
* other kids will send and will be left with zombies. Using a while loop
|
||||||
|
* tries to avoid this (or at least minimize the probability), by calling
|
||||||
|
* waitpid until there are no more exited kids that respond.
|
||||||
|
* I think there is still a small probability that a a SIGCHLD signal can
|
||||||
|
* arrive after we finished the while loop, but before we return.
|
||||||
|
* Passing SA_NODEFER to the SIGCHLD handler doesn't seem to help at all,
|
||||||
|
* though tha man page sais that using this flag should allow receival of
|
||||||
|
* other SIGCHLD signals while processing one. Why is this? -Dan
|
||||||
|
*
|
||||||
|
* There seem to be SA_NOCLDWAIT, but I'm not sure its available on all
|
||||||
|
* platforms, and its possible that even if it will prevent zombie
|
||||||
|
* generation, it may also prevent us from receiving the exit status
|
||||||
|
* of our kids (I'm not sure, because the man page doesn't state this
|
||||||
|
* clearly). -Dan
|
||||||
|
*
|
||||||
|
* Maybe the best way would be to forget about SA_NODEFER and do it the
|
||||||
|
* old way: unblock SIGCHLD immediately after we entered this handler,
|
||||||
|
* then call waitpid in a while loop to get the exit status of all kids
|
||||||
|
* that exited while SIGCHLD was blocked and we missed the signal.
|
||||||
|
* This way there is no way we can miss any kid, because the while loop
|
||||||
|
* takes care of signals that were missed before we reenabled SIGCHLD
|
||||||
|
* and after enabling the signal, we we start getting them even if we
|
||||||
|
* are in the signal handler itself. Only need to check if it doesn't
|
||||||
|
* have any problem with reentrancy, but I don't think so. -Dan
|
||||||
|
*/
|
||||||
|
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||||
NotifyDeadProcess(pid, WEXITSTATUS(status));
|
NotifyDeadProcess(pid, WEXITSTATUS(status));
|
||||||
/*
|
/*
|
||||||
* Make sure that the kid will be buried even if there are
|
* Make sure that the kid will be buried even if there are
|
||||||
@@ -793,8 +824,9 @@ StartUp(Bool defaultScreenOnly)
|
|||||||
sigaction(SIGPIPE, &sig_action, NULL);
|
sigaction(SIGPIPE, &sig_action, NULL);
|
||||||
|
|
||||||
/* handle dead children */
|
/* handle dead children */
|
||||||
|
/* Using SA_NODEFER doesn't seem to have any effect. Why? -Dan */
|
||||||
sig_action.sa_handler = buryChild;
|
sig_action.sa_handler = buryChild;
|
||||||
sig_action.sa_flags = SA_NOCLDSTOP|SA_RESTART;
|
sig_action.sa_flags = SA_NODEFER|SA_NOCLDSTOP|SA_RESTART;
|
||||||
sigaction(SIGCHLD, &sig_action, NULL);
|
sigaction(SIGCHLD, &sig_action, NULL);
|
||||||
|
|
||||||
/* Now we unblock all signals, that may have been blocked by the parent
|
/* Now we unblock all signals, that may have been blocked by the parent
|
||||||
|
|||||||
Reference in New Issue
Block a user