Skip to content
Permalink
Browse files

handle SIGCONT

  • Loading branch information...
rt
rt committed Apr 29, 2019
1 parent 3898fd5 commit e0ff5b89411584357a5c1905fbd80c32ecee194f
@@ -191,7 +191,8 @@ void CUnitLoader::GiveUnits(const std::string& objectName, float3 pos, int amoun
pos.z = Clamp(pos.z, sqHalfMapSize, float3::maxzpos - sqHalfMapSize - 1);

for (int a = 1; a <= numRequestedUnits; ++a) {
Watchdog::ClearPrimaryTimers(); // the other thread may be waiting for a mutex held by this one, triggering hang detection
Watchdog::ClearTimers(false, true);

const float px = pos.x + (a % sqSize - sqSize / 2) * 10 * SQUARE_SIZE;
const float pz = pos.z + (a / sqSize - sqSize / 2) * 10 * SQUARE_SIZE;
const UnitDef* ud = unitDefHandler->GetUnitDefByID(a);
@@ -255,7 +256,7 @@ void CUnitLoader::GiveUnits(const std::string& objectName, float3 pos, int amoun
const float px = squarePos.x + x * xsize * SQUARE_SIZE;
const float pz = squarePos.z + z * zsize * SQUARE_SIZE;

Watchdog::ClearPrimaryTimers();
Watchdog::ClearTimers(false, true);

const UnitLoadParams unitParams = {
unitDef,
@@ -301,7 +302,7 @@ void CUnitLoader::GiveUnits(const std::string& objectName, float3 pos, int amoun
const float pz = squarePos.z + z * zsize * SQUARE_SIZE;
const float3 featurePos = float3(px, CGround::GetHeightReal(px, pz), pz);

Watchdog::ClearPrimaryTimers();
Watchdog::ClearTimers(false, true);
FeatureLoadParams params = {
featureDef,
nullptr,
@@ -941,21 +941,31 @@ namespace CrashHandler

void HandleSignal(int signal, siginfo_t* siginfo, void* pctx)
{
if (signal == SIGINT) {
// ctrl+c = kill
LOG("caught SIGINT, aborting");

// first try a clean exit
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);

// abort after 5sec
spring::thread(std::bind(&ForcedExitAfterFiveSecs));
spring::thread(std::bind(&ForcedExitAfterTenSecs));
return;
switch (signal) {
case SIGINT: {
// ctrl+c = kill
LOG("[%s] caught SIGINT, aborting", __func__);

// first try a clean exit
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);

// abort after 5sec
spring::thread(std::bind(&ForcedExitAfterFiveSecs));
spring::thread(std::bind(&ForcedExitAfterTenSecs));
return;
} break;
case SIGCONT: {
Watchdog::ClearTimers(false, false);
LOG("[%s] caught SIGCONT, resuming", __func__);
return;
} break;
default: {
} break;
}


// turn off signal handling for this signal temporarily in order to disable recursive events (e.g. SIGSEGV)
if ((++reentrances) >= 2) {
sigaction_t& sa = GetSigAction(nullptr);
@@ -1045,6 +1055,8 @@ namespace CrashHandler
sigaction(SIGFPE, &sa, nullptr); // div0 and more
sigaction(SIGABRT, &sa, nullptr);
sigaction(SIGINT, &sa, nullptr);
// sigaction(SIGSTOP, &sa, nullptr); // cannot be caught
sigaction(SIGCONT, &sa, nullptr);
sigaction(SIGBUS, &sa, nullptr); // on macosx EXC_BAD_ACCESS (mach exception) is translated to SIGBUS

std::set_new_handler(NewHandler);
@@ -1061,6 +1073,8 @@ namespace CrashHandler
sigaction(SIGFPE, &sa, nullptr);
sigaction(SIGABRT, &sa, nullptr);
sigaction(SIGINT, &sa, nullptr);
// sigaction(SIGSTOP, &sa, nullptr);
sigaction(SIGCONT, &sa, nullptr);
sigaction(SIGBUS, &sa, nullptr);

std::set_new_handler(nullptr);
@@ -351,14 +351,16 @@ namespace Watchdog
threadInfo->timer = disable ? spring_notime : spring_gettime();
}

void ClearPrimaryTimers(bool disable)
void ClearTimers(bool disable, bool primary)
{
// bail if Watchdog is not running
if (!hangDetectorThread.joinable())
return; //! Watchdog isn't running
return;

for (unsigned int i = 0; i < WDT_COUNT; ++i) {
WatchDogThreadInfo* threadInfo = registeredThreads[i];
if (threadSlots[i].primary)

if (!primary || threadSlots[i].primary)
threadInfo->timer = disable ? spring_notime : spring_gettime();
}
}
@@ -17,17 +17,17 @@ enum WatchdogThreadnum {

namespace Watchdog
{
//! Installs the watchdog thread
// Installs the watchdog thread
void Install();
void Uninstall();

//! Call this to reset the watchdog timer of the current thread
// Call this to reset the watchdog timer of the current thread
void ClearTimer(Threading::NativeThreadId* _threadId = nullptr, bool disable = false);
void ClearTimer(const WatchdogThreadnum num, bool disable = false);
void ClearTimer(const char* name, bool disable = false);
void ClearPrimaryTimers(bool disable = false);
void ClearTimers(bool disable = false, bool primary = false);

//! Call these in the threads you want to monitor
// Call these in the threads you want to monitor
void RegisterThread(WatchdogThreadnum num, bool primary = false);
bool DeregisterThread(WatchdogThreadnum num);
bool DeregisterCurrentThread();

0 comments on commit e0ff5b8

Please sign in to comment.
You can’t perform that action at this time.