aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
authorMai <mathew1800@gmail.com>2022-11-09 03:25:53 +0000
committerGitHub <noreply@github.com>2022-11-09 03:25:53 +0000
commitad9e5bc5b7374d87d0b4f47ad7b1a6def78132c8 (patch)
tree58c88d7ca923789c9a5d5518d2af1e413887f451 /src/core/hle/kernel/kernel.cpp
parentdc520a487d17ac377b26ee531d48f5ed64c42851 (diff)
parent6a0d8b2aa154921e8328dfab9450510ad8e1b5c8 (diff)
Merge pull request #9199 from liamwhite/service-oops
service_thread: fix deletion
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp42
1 files changed, 20 insertions, 22 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 47b760a9cb..abff140794 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -93,7 +93,7 @@ struct KernelCore::Impl {
RegisterHostThread();
- default_service_thread = CreateServiceThread(kernel, "DefaultServiceThread");
+ default_service_thread = &CreateServiceThread(kernel, "DefaultServiceThread");
}
void InitializeCores() {
@@ -779,33 +779,31 @@ struct KernelCore::Impl {
search->second(system.ServiceManager(), server_port);
}
- std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(KernelCore& kernel,
- const std::string& name) {
- auto service_thread = std::make_shared<Kernel::ServiceThread>(kernel, name);
+ Kernel::ServiceThread& CreateServiceThread(KernelCore& kernel, const std::string& name) {
+ auto* ptr = new ServiceThread(kernel, name);
service_threads_manager.QueueWork(
- [this, service_thread]() { service_threads.emplace(service_thread); });
+ [this, ptr]() { service_threads.emplace(ptr, std::unique_ptr<ServiceThread>(ptr)); });
- return service_thread;
+ return *ptr;
}
- void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) {
- if (auto strong_ptr = service_thread.lock()) {
- if (strong_ptr == default_service_thread.lock()) {
- // Nothing to do here, the service is using default_service_thread, which will be
- // released on shutdown.
- return;
- }
+ void ReleaseServiceThread(Kernel::ServiceThread& service_thread) {
+ auto* ptr = &service_thread;
- service_threads_manager.QueueWork(
- [this, strong_ptr{std::move(strong_ptr)}]() { service_threads.erase(strong_ptr); });
+ if (ptr == default_service_thread) {
+ // Nothing to do here, the service is using default_service_thread, which will be
+ // released on shutdown.
+ return;
}
+
+ service_threads_manager.QueueWork([this, ptr]() { service_threads.erase(ptr); });
}
void ClearServiceThreads() {
service_threads_manager.QueueWork([this] {
service_threads.clear();
- default_service_thread.reset();
+ default_service_thread = nullptr;
service_thread_barrier.Sync();
});
service_thread_barrier.Sync();
@@ -881,8 +879,8 @@ struct KernelCore::Impl {
std::unique_ptr<KMemoryLayout> memory_layout;
// Threads used for services
- std::unordered_set<std::shared_ptr<ServiceThread>> service_threads;
- std::weak_ptr<ServiceThread> default_service_thread;
+ std::unordered_map<ServiceThread*, std::unique_ptr<ServiceThread>> service_threads;
+ ServiceThread* default_service_thread{};
Common::ThreadWorker service_threads_manager;
Common::Barrier service_thread_barrier;
@@ -1239,15 +1237,15 @@ void KernelCore::ExitSVCProfile() {
MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]);
}
-std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) {
+Kernel::ServiceThread& KernelCore::CreateServiceThread(const std::string& name) {
return impl->CreateServiceThread(*this, name);
}
-std::weak_ptr<Kernel::ServiceThread> KernelCore::GetDefaultServiceThread() const {
- return impl->default_service_thread;
+Kernel::ServiceThread& KernelCore::GetDefaultServiceThread() const {
+ return *impl->default_service_thread;
}
-void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) {
+void KernelCore::ReleaseServiceThread(Kernel::ServiceThread& service_thread) {
impl->ReleaseServiceThread(service_thread);
}