- Make sure a hung worker thread always crashes the application

This commit is contained in:
Magnus Norddahl 2017-05-21 12:03:12 +02:00
parent aff9205057
commit e27e89b57d
3 changed files with 38 additions and 2 deletions

View file

@ -33,6 +33,11 @@
#include "r_thread.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
#include <chrono>
#ifdef WIN32
void PeekThreadedErrorPane();
#endif
CVAR(Bool, r_multithreaded, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
@ -73,10 +78,20 @@ void DrawerThreads::Execute(DrawerCommandQueuePtr commands)
void DrawerThreads::WaitForWorkers()
{
using namespace std::chrono_literals;
// Wait for workers to finish
auto queue = Instance();
std::unique_lock<std::mutex> end_lock(queue->end_mutex);
queue->end_condition.wait(end_lock, [&]() { return queue->tasks_left == 0; });
if (!queue->end_condition.wait_for(end_lock, 5s, [&]() { return queue->tasks_left == 0; }))
{
#ifdef WIN32
PeekThreadedErrorPane();
#endif
// Invoke the crash reporter so that we can capture the call stack of whatever the hung worker thread is doing
int *threadCrashed = nullptr;
*threadCrashed = 0xdeadbeef;
}
end_lock.unlock();
// Clean up

View file

@ -57,6 +57,11 @@
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
#include "swrenderer/things/r_playersprite.h"
#include <chrono>
#ifdef WIN32
void PeekThreadedErrorPane();
#endif
EXTERN_CVAR(Bool, r_shadercolormaps)
EXTERN_CVAR(Int, r_clearbuffer)
@ -217,9 +222,18 @@ namespace swrenderer
// Wait for everyone to finish:
if (Threads.size() > 1)
{
using namespace std::chrono_literals;
std::unique_lock<std::mutex> end_lock(end_mutex);
finished_threads++;
end_condition.wait(end_lock, [&]() { return finished_threads == Threads.size(); });
if (!end_condition.wait_for(end_lock, 5s, [&]() { return finished_threads == Threads.size(); }))
{
#ifdef WIN32
PeekThreadedErrorPane();
#endif
// Invoke the crash reporter so that we can capture the call stack of whatever the hung worker thread is doing
int *threadCrashed = nullptr;
*threadCrashed = 0xdeadbeef;
}
finished_threads = 0;
}

View file

@ -821,6 +821,13 @@ void ShowErrorPane(const char *text)
}
}
void PeekThreadedErrorPane()
{
// Allow SendMessage from another thread to call its message handler so that it can display the crash dialog
MSG msg;
PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE);
}
//==========================================================================
//
// DoMain