mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
Fix race in render_creator (#9939)
This commit is contained in:
parent
43ac33c2b4
commit
ad49c54531
@ -31,43 +31,49 @@ render_creator::render_creator(QObject *parent) : QObject(parent)
|
||||
|
||||
static std::mutex mtx;
|
||||
static std::condition_variable cond;
|
||||
static bool thread_running = true;
|
||||
static bool device_found = false;
|
||||
static bool work_done = false;
|
||||
|
||||
static QStringList compatible_gpus;
|
||||
|
||||
auto enum_thread_v = new named_thread("Vulkan Device Enumeration Thread"sv, [&]()
|
||||
auto enum_thread_v = new named_thread("Vulkan Device Enumeration Thread"sv, [&, adapters = &this->vulkan_adapters]()
|
||||
{
|
||||
thread_ctrl::scoped_priority low_prio(-1);
|
||||
|
||||
vk::instance device_enum_context;
|
||||
|
||||
std::unique_lock lock(mtx, std::defer_lock);
|
||||
|
||||
if (device_enum_context.create("RPCS3", true))
|
||||
{
|
||||
device_enum_context.bind();
|
||||
std::vector<vk::physical_device>& gpus = device_enum_context.enumerate_devices();
|
||||
|
||||
if (!gpus.empty())
|
||||
{
|
||||
device_found = true;
|
||||
lock.lock();
|
||||
|
||||
if (!work_done) // The spawning thread gave up, do not attempt to modify vulkan_adapters
|
||||
{
|
||||
for (auto& gpu : gpus)
|
||||
{
|
||||
compatible_gpus.append(qstr(gpu.get_name()));
|
||||
adapters->append(qstr(gpu.get_name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
std::scoped_lock{ mtx }, thread_running = false;
|
||||
work_done = true;
|
||||
lock.unlock();
|
||||
cond.notify_all();
|
||||
});
|
||||
|
||||
std::unique_ptr<std::remove_pointer_t<decltype(enum_thread_v)>> enum_thread(enum_thread_v);
|
||||
|
||||
if ([&]()
|
||||
{
|
||||
std::unique_lock lck(mtx);
|
||||
cond.wait_for(lck, std::chrono::seconds(10), [&] { return !thread_running; });
|
||||
}
|
||||
|
||||
if (thread_running)
|
||||
cond.wait_for(lck, std::chrono::seconds(10), [&] { return work_done; });
|
||||
return !std::exchange(work_done, true); // If thread hasn't done its job yet, it won't anymore
|
||||
}())
|
||||
{
|
||||
enum_thread.release(); // Detach thread (destructor is not called)
|
||||
|
||||
@ -88,8 +94,7 @@ render_creator::render_creator(QObject *parent) : QObject(parent)
|
||||
}
|
||||
else
|
||||
{
|
||||
supports_vulkan = device_found;
|
||||
vulkan_adapters = std::move(compatible_gpus);
|
||||
supports_vulkan = !vulkan_adapters.isEmpty();
|
||||
enum_thread.reset(); // Join thread
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user