mirror of
https://github.com/love2d/love.git
synced 2026-08-20 12:40:20 +02:00
Disable signal handling in threads (see issue #1042)
I don't necessarily like having to do these extra calls whenever threads are spawned (and what happens to signals during the time signal delivery is disabled?) but it seems to fully fix os.execute. NOTE: Also disables signals when loading openal, as it or one of its backends spawns threads internally, and does not disable signals itself. --HG-- branch : minor
This commit is contained in:
@@ -96,6 +96,11 @@ Audio::Audio()
|
|||||||
, poolThread(nullptr)
|
, poolThread(nullptr)
|
||||||
, distanceModel(DISTANCE_INVERSE_CLAMPED)
|
, distanceModel(DISTANCE_INVERSE_CLAMPED)
|
||||||
{
|
{
|
||||||
|
#if defined(LOVE_LINUX)
|
||||||
|
// Temporarly block signals, as the thread inherits this mask
|
||||||
|
love::thread::disableSignals();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Passing null for default device.
|
// Passing null for default device.
|
||||||
device = alcOpenDevice(nullptr);
|
device = alcOpenDevice(nullptr);
|
||||||
|
|
||||||
@@ -116,6 +121,10 @@ Audio::Audio()
|
|||||||
if (!alcMakeContextCurrent(context) || alcGetError(device) != ALC_NO_ERROR)
|
if (!alcMakeContextCurrent(context) || alcGetError(device) != ALC_NO_ERROR)
|
||||||
throw love::Exception("Could not make context current.");
|
throw love::Exception("Could not make context current.");
|
||||||
|
|
||||||
|
#if defined(LOVE_LINUX)
|
||||||
|
love::thread::reenableSignals();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ALC_EXT_EFX
|
#ifdef ALC_EXT_EFX
|
||||||
initializeEFX();
|
initializeEFX();
|
||||||
|
|
||||||
|
|||||||
@@ -42,20 +42,6 @@
|
|||||||
#include <spawn.h>
|
#include <spawn.h>
|
||||||
#endif
|
#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 love
|
||||||
{
|
{
|
||||||
namespace system
|
namespace system
|
||||||
@@ -63,18 +49,6 @@ namespace system
|
|||||||
|
|
||||||
System::System()
|
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 = sigchld_handler;
|
|
||||||
act.sa_flags = SA_RESTART;
|
|
||||||
sigaction(SIGCHLD, &act, nullptr);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string System::getOS() const
|
std::string System::getOS() const
|
||||||
|
|||||||
@@ -42,6 +42,11 @@ Thread::~Thread()
|
|||||||
|
|
||||||
bool Thread::start()
|
bool Thread::start()
|
||||||
{
|
{
|
||||||
|
#if defined(LOVE_LINUX)
|
||||||
|
// Temporarly block signals, as the thread inherits this mask
|
||||||
|
love::thread::disableSignals();
|
||||||
|
#endif
|
||||||
|
|
||||||
Lock l(mutex);
|
Lock l(mutex);
|
||||||
if (running)
|
if (running)
|
||||||
return false;
|
return false;
|
||||||
@@ -49,6 +54,10 @@ bool Thread::start()
|
|||||||
SDL_WaitThread(thread, nullptr);
|
SDL_WaitThread(thread, nullptr);
|
||||||
thread = SDL_CreateThread(thread_runner, t->getThreadName(), this);
|
thread = SDL_CreateThread(thread_runner, t->getThreadName(), this);
|
||||||
running = (thread != nullptr);
|
running = (thread != nullptr);
|
||||||
|
|
||||||
|
#if defined(LOVE_LINUX)
|
||||||
|
love::thread::reenableSignals();
|
||||||
|
#endif
|
||||||
return running;
|
return running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,10 @@
|
|||||||
|
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
|
|
||||||
|
#if defined(LOVE_LINUX)
|
||||||
|
#include <signal.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
namespace thread
|
namespace thread
|
||||||
@@ -153,5 +157,21 @@ Conditional *ConditionalRef::operator->() const
|
|||||||
return conditional;
|
return conditional;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(LOVE_LINUX)
|
||||||
|
static sigset_t oldset;
|
||||||
|
|
||||||
|
void disableSignals()
|
||||||
|
{
|
||||||
|
sigset_t newset;
|
||||||
|
sigfillset(&newset);
|
||||||
|
pthread_sigmask(SIG_SETMASK, &newset, &oldset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reenableSignals()
|
||||||
|
{
|
||||||
|
pthread_sigmask(SIG_SETMASK, &oldset, nullptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // thread
|
} // thread
|
||||||
} // love
|
} // love
|
||||||
|
|||||||
@@ -129,6 +129,11 @@ Mutex *newMutex();
|
|||||||
Conditional *newConditional();
|
Conditional *newConditional();
|
||||||
Thread *newThread(Threadable *t);
|
Thread *newThread(Threadable *t);
|
||||||
|
|
||||||
|
#if defined(LOVE_LINUX)
|
||||||
|
void disableSignals();
|
||||||
|
void reenableSignals();
|
||||||
|
#endif
|
||||||
|
|
||||||
} // thread
|
} // thread
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user