Improve reaping of zombie processes on linux (resolves #1042)

Sadly, it's not a complete fix for #1042, as there seems to be no good way to
deal with system() in multithreaded applications. At least os.execute can
return values other than -1 now.
This commit is contained in:
Bart van Strien
2016-03-14 17:14:49 +01:00
parent d0c0240e09
commit f7d226d072
+20 -4
View File
@@ -41,6 +41,20 @@
#pragma comment(lib, "shell32.lib")
#endif
#if defined(LOVE_LINUX)
static void sigchld_handler(int sig)
{
// Because waitpid can set errno, we need to save it.
auto old = errno;
// Reap whilst there are children waiting to be reaped.
while (waitpid(-1, nullptr, WNOHANG) > 0)
;
errno = old;
}
#endif
namespace love
{
namespace system
@@ -50,12 +64,14 @@ System::System()
{
#if defined(LOVE_LINUX)
// Enable automatic cleanup of zombie processes
// NOTE: We're using our own handler, instead of SA_NOCLDWAIT because the
// latter breaks wait, and thus os.execute.
// NOTE: This isn't perfect, due to multithreading our SIGCHLD can happen
// on a different thread than the one calling wait(), thus causing a race.
struct sigaction act = {0};
sigemptyset(&act.sa_mask);
act.sa_handler = SIG_DFL;
act.sa_flags = SA_NOCLDWAIT;
// Requires linux 2.6 or higher, so anything remotely modern
act.sa_handler = sigchld_handler;
act.sa_flags = SA_RESTART;
sigaction(SIGCHLD, &act, nullptr);
#endif
}