mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 22:11:26 +12:00
Fix race in render_creator (#9939)
This commit is contained in:
parent
43ac33c2b4
commit
ad49c54531
1 changed files with 21 additions and 16 deletions
|
@ -31,43 +31,49 @@ render_creator::render_creator(QObject *parent) : QObject(parent)
|
||||||
|
|
||||||
static std::mutex mtx;
|
static std::mutex mtx;
|
||||||
static std::condition_variable cond;
|
static std::condition_variable cond;
|
||||||
static bool thread_running = true;
|
static bool work_done = false;
|
||||||
static bool device_found = false;
|
|
||||||
|
|
||||||
static QStringList compatible_gpus;
|
auto enum_thread_v = new named_thread("Vulkan Device Enumeration Thread"sv, [&, adapters = &this->vulkan_adapters]()
|
||||||
|
|
||||||
auto enum_thread_v = new named_thread("Vulkan Device Enumeration Thread"sv, [&]()
|
|
||||||
{
|
{
|
||||||
thread_ctrl::scoped_priority low_prio(-1);
|
thread_ctrl::scoped_priority low_prio(-1);
|
||||||
|
|
||||||
vk::instance device_enum_context;
|
vk::instance device_enum_context;
|
||||||
|
|
||||||
|
std::unique_lock lock(mtx, std::defer_lock);
|
||||||
|
|
||||||
if (device_enum_context.create("RPCS3", true))
|
if (device_enum_context.create("RPCS3", true))
|
||||||
{
|
{
|
||||||
device_enum_context.bind();
|
device_enum_context.bind();
|
||||||
std::vector<vk::physical_device>& gpus = device_enum_context.enumerate_devices();
|
std::vector<vk::physical_device>& gpus = device_enum_context.enumerate_devices();
|
||||||
|
|
||||||
if (!gpus.empty())
|
lock.lock();
|
||||||
{
|
|
||||||
device_found = true;
|
|
||||||
|
|
||||||
|
if (!work_done) // The spawning thread gave up, do not attempt to modify vulkan_adapters
|
||||||
|
{
|
||||||
for (auto& gpu : gpus)
|
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();
|
cond.notify_all();
|
||||||
});
|
});
|
||||||
|
|
||||||
std::unique_ptr<std::remove_pointer_t<decltype(enum_thread_v)>> enum_thread(enum_thread_v);
|
std::unique_ptr<std::remove_pointer_t<decltype(enum_thread_v)>> enum_thread(enum_thread_v);
|
||||||
|
|
||||||
|
if ([&]()
|
||||||
{
|
{
|
||||||
std::unique_lock lck(mtx);
|
std::unique_lock lck(mtx);
|
||||||
cond.wait_for(lck, std::chrono::seconds(10), [&] { return !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
|
||||||
|
}())
|
||||||
if (thread_running)
|
|
||||||
{
|
{
|
||||||
enum_thread.release(); // Detach thread (destructor is not called)
|
enum_thread.release(); // Detach thread (destructor is not called)
|
||||||
|
|
||||||
|
@ -88,8 +94,7 @@ render_creator::render_creator(QObject *parent) : QObject(parent)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
supports_vulkan = device_found;
|
supports_vulkan = !vulkan_adapters.isEmpty();
|
||||||
vulkan_adapters = std::move(compatible_gpus);
|
|
||||||
enum_thread.reset(); // Join thread
|
enum_thread.reset(); // Join thread
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue