diff options
author | bunnei <bunneidev@gmail.com> | 2020-12-29 10:06:39 +0100 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2020-12-29 10:06:39 +0100 |
commit | f57be2e62603ddd99fbdb1dea1bfc91ee2d7fc04 (patch) | |
tree | 3b5fe338ccb80cec8f06e7a49888abb9af010cc2 /src/core | |
parent | hle: service: Acquire and release a lock on requests. (diff) | |
download | yuzu-f57be2e62603ddd99fbdb1dea1bfc91ee2d7fc04.tar yuzu-f57be2e62603ddd99fbdb1dea1bfc91ee2d7fc04.tar.gz yuzu-f57be2e62603ddd99fbdb1dea1bfc91ee2d7fc04.tar.bz2 yuzu-f57be2e62603ddd99fbdb1dea1bfc91ee2d7fc04.tar.lz yuzu-f57be2e62603ddd99fbdb1dea1bfc91ee2d7fc04.tar.xz yuzu-f57be2e62603ddd99fbdb1dea1bfc91ee2d7fc04.tar.zst yuzu-f57be2e62603ddd99fbdb1dea1bfc91ee2d7fc04.zip |
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/hle/kernel/server_session.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/kernel/service_thread.cpp | 28 | ||||
-rw-r--r-- | src/core/hle/kernel/service_thread.h | 3 |
3 files changed, 22 insertions, 11 deletions
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index ed42452ff..947f4a133 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -34,7 +34,7 @@ ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kern session->name = std::move(name); session->parent = std::move(parent); - session->service_thread = std::make_unique<ServiceThread>(kernel, 1); + session->service_thread = std::make_unique<ServiceThread>(kernel, 1, session->name); return MakeResult(std::move(session)); } diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp index 4ceb7e56a..1c134777f 100644 --- a/src/core/hle/kernel/service_thread.cpp +++ b/src/core/hle/kernel/service_thread.cpp @@ -11,6 +11,7 @@ #include "common/assert.h" #include "common/scope_exit.h" +#include "common/thread.h" #include "core/core.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/server_session.h" @@ -22,7 +23,7 @@ namespace Kernel { class ServiceThread::Impl final { public: - explicit Impl(KernelCore& kernel, std::size_t num_threads); + explicit Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name); ~Impl(); void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context); @@ -32,12 +33,16 @@ private: std::queue<std::function<void()>> requests; std::mutex queue_mutex; std::condition_variable condition; + const std::string service_name; bool stop{}; }; -ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads) { +ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name) + : service_name{name} { for (std::size_t i = 0; i < num_threads; ++i) - threads.emplace_back([&] { + threads.emplace_back([this, &kernel] { + Common::SetCurrentThreadName(std::string{"Hle_" + service_name}.c_str()); + // Wait for first request before trying to acquire a render context { std::unique_lock lock{queue_mutex}; @@ -52,7 +57,7 @@ ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads) { { std::unique_lock lock{queue_mutex}; condition.wait(lock, [this] { return stop || !requests.empty(); }); - if (stop && requests.empty()) { + if (stop || requests.empty()) { return; } task = std::move(requests.front()); @@ -68,9 +73,14 @@ void ServiceThread::Impl::QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context) { { std::unique_lock lock{queue_mutex}; - requests.emplace([session{SharedFrom(&session)}, context{std::move(context)}]() { - session->CompleteSyncRequest(*context); - return; + + // ServerSession owns the service thread, so we cannot caption a strong pointer here in the + // event that the ServerSession is terminated. + std::weak_ptr<ServerSession> weak_ptr{SharedFrom(&session)}; + requests.emplace([weak_ptr, context{std::move(context)}]() { + if (auto strong_ptr = weak_ptr.lock()) { + strong_ptr->CompleteSyncRequest(*context); + } }); } condition.notify_one(); @@ -87,8 +97,8 @@ ServiceThread::Impl::~Impl() { } } -ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads) - : impl{std::make_unique<Impl>(kernel, num_threads)} {} +ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name) + : impl{std::make_unique<Impl>(kernel, num_threads, name)} {} ServiceThread::~ServiceThread() = default; diff --git a/src/core/hle/kernel/service_thread.h b/src/core/hle/kernel/service_thread.h index 91ad7ae85..025ab8fb5 100644 --- a/src/core/hle/kernel/service_thread.h +++ b/src/core/hle/kernel/service_thread.h @@ -5,6 +5,7 @@ #pragma once #include <memory> +#include <string> namespace Kernel { @@ -14,7 +15,7 @@ class ServerSession; class ServiceThread final { public: - explicit ServiceThread(KernelCore& kernel, std::size_t num_threads); + explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name); ~ServiceThread(); void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context); |