Skip to content

Commit

Permalink
Improve reaping of zombie processes on linux (resolves love2d#1042)
Browse files Browse the repository at this point in the history
Sadly, it's not a complete fix for love2d#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.
  • Loading branch information
bartbes committed Mar 14, 2016
1 parent d0c0240 commit f7d226d
Showing 1 changed file with 20 additions and 4 deletions.
24 changes: 20 additions & 4 deletions src/modules/system/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}
Expand Down

0 comments on commit f7d226d

Please sign in to comment.