diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | src/event/SignalMonitor.cxx | 23 |
2 files changed, 24 insertions, 1 deletions
@@ -3,6 +3,8 @@ ver 0.18.9 (not yet released) - vorbis: fix linker failure when libvorbis/libogg are static * encoder - vorbis: fix another linker failure +* output + - pipe: fix hanging child process due to blocked signals ver 0.18.8 (2014/02/07) * decoder diff --git a/src/event/SignalMonitor.cxx b/src/event/SignalMonitor.cxx index 8c8527a77..eda52aba1 100644 --- a/src/event/SignalMonitor.cxx +++ b/src/event/SignalMonitor.cxx @@ -39,6 +39,10 @@ #include <algorithm> +#ifdef USE_SIGNALFD +#include <pthread.h> +#endif + class SignalMonitor final : private SocketMonitor { #ifdef USE_SIGNALFD SignalFD fd; @@ -99,7 +103,21 @@ static std::atomic_bool signal_pending[MAX_SIGNAL]; static Manual<SignalMonitor> monitor; -#ifndef USE_SIGNALFD +#ifdef USE_SIGNALFD + +/** + * This is a pthread_atfork() callback that unblocks the signals that + * were blocked for our signalfd(). Without this, our child processes + * would inherit the blocked signals. + */ +static void +at_fork_child() +{ + sigprocmask(SIG_UNBLOCK, &signal_mask, nullptr); +} + +#else + static void SignalCallback(int signo) { @@ -108,6 +126,7 @@ SignalCallback(int signo) if (!signal_pending[signo].exchange(true)) monitor->WakeUp(); } + #endif void @@ -115,6 +134,8 @@ SignalMonitorInit(EventLoop &loop) { #ifdef USE_SIGNALFD sigemptyset(&signal_mask); + + pthread_atfork(nullptr, nullptr, at_fork_child); #endif monitor.Construct(loop); |