mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- Make sure a hung worker thread always crashes the application
This commit is contained in:
parent
aff9205057
commit
e27e89b57d
3 changed files with 38 additions and 2 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue