screen: use condition_variable rather than polling for next frame

Use a timeout to prevent deadlocks when unloading games/if no frames are prevented.
This commit is contained in:
Luke Usher committed 2024-04-02 11:39:23 +01:00
1 parent 0af2690e50
commit b145f0f000
3 files changed
+13 -3

No files matched your search

+9 -3
View File
@@ -25,11 +25,15 @@ Screen::~Screen() {
auto Screen::main(uintptr_t) -> void {
while(!_kill) {
usleep(1);
if(_frame) {
unique_lock<mutex> lock(_frameMutex);
auto timeout = std::chrono::milliseconds(10);
if(_frameCondition.wait_for(lock, timeout, [&] { return _frame.load(); })) {
refresh();
_frame = false;
}
if(_kill) break;
}
}
@@ -181,10 +185,12 @@ auto Screen::frame() -> void {
lock_guard<recursive_mutex> lock(_mutex);
_inputA.swap(_inputB);
_frame = true;
if constexpr(!ares::Video::Threaded) {
refresh();
_frame = false;
} else {
_frame = true;
_frameCondition.notify_one();
}
}
+2
View File
@@ -97,6 +97,8 @@ protected:
//unserialized:
nall::thread _thread;
recursive_mutex _mutex;
mutex _frameMutex;
condition_variable _frameCondition;
atomic<bool> _kill = false;
atomic<bool> _frame = false;
function<void ()> _refresh;
+2
View File
@@ -13,8 +13,10 @@
namespace nall {
using mutex = std::mutex;
using recursive_mutex = std::recursive_mutex;
using condition_variable = std::condition_variable;
template<typename T> using lock_guard = std::lock_guard<T>;
template<typename T> using atomic = std::atomic<T>;
template<typename T> using unique_lock = std::unique_lock<T>;
}
#if defined(API_POSIX)