summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp11
-rw-r--r--src/core/hle/kernel/hle_ipc.h22
-rw-r--r--src/core/hle/kernel/k_auto_object.h11
-rw-r--r--src/core/hle/kernel/k_auto_object_container.cpp4
-rw-r--r--src/core/hle/kernel/k_auto_object_container.h5
-rw-r--r--src/core/hle/kernel/k_client_port.cpp9
-rw-r--r--src/core/hle/kernel/k_client_port.h4
-rw-r--r--src/core/hle/kernel/k_client_session.h4
-rw-r--r--src/core/hle/kernel/k_readable_event.h4
-rw-r--r--src/core/hle/kernel/k_server_port.cpp4
-rw-r--r--src/core/hle/kernel/k_server_port.h2
-rw-r--r--src/core/hle/kernel/k_server_session.cpp25
-rw-r--r--src/core/hle/kernel/k_server_session.h17
-rw-r--r--src/core/hle/kernel/k_session.cpp5
-rw-r--r--src/core/hle/kernel/k_session.h5
-rw-r--r--src/core/hle/kernel/k_writable_event.cpp4
-rw-r--r--src/core/hle/result.h40
-rw-r--r--src/core/hle/service/ns/pl_u.cpp2
-rw-r--r--src/core/hle/service/service.cpp6
-rw-r--r--src/core/hle/service/service.h5
-rw-r--r--src/core/hle/service/sm/controller.cpp37
-rw-r--r--src/core/hle/service/sm/sm.cpp2
22 files changed, 121 insertions, 107 deletions
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 2b5c30f7a..260af87e5 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -30,9 +30,16 @@
namespace Kernel {
-SessionRequestHandler::SessionRequestHandler() = default;
+SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_)
+ : kernel{kernel_}, service_thread{kernel.CreateServiceThread(service_name_)} {}
-SessionRequestHandler::~SessionRequestHandler() = default;
+SessionRequestHandler::~SessionRequestHandler() {
+ kernel.ReleaseServiceThread(service_thread);
+}
+
+SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kernel_} {}
+
+SessionRequestManager::~SessionRequestManager() = default;
void SessionRequestHandler::ClientConnected(KServerSession* session) {
session->SetSessionHandler(shared_from_this());
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index b47e363cc..2aaf93fca 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -46,6 +46,7 @@ class KThread;
class KReadableEvent;
class KSession;
class KWritableEvent;
+class ServiceThread;
enum class ThreadWakeupReason;
@@ -56,7 +57,7 @@ enum class ThreadWakeupReason;
*/
class SessionRequestHandler : public std::enable_shared_from_this<SessionRequestHandler> {
public:
- SessionRequestHandler();
+ SessionRequestHandler(KernelCore& kernel, const char* service_name_);
virtual ~SessionRequestHandler();
/**
@@ -83,6 +84,14 @@ public:
* @param server_session ServerSession associated with the connection.
*/
void ClientDisconnected(KServerSession* session);
+
+ std::shared_ptr<ServiceThread> GetServiceThread() const {
+ return service_thread.lock();
+ }
+
+protected:
+ KernelCore& kernel;
+ std::weak_ptr<ServiceThread> service_thread;
};
using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;
@@ -94,7 +103,8 @@ using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;
*/
class SessionRequestManager final {
public:
- SessionRequestManager() = default;
+ explicit SessionRequestManager(KernelCore& kernel);
+ ~SessionRequestManager();
bool IsDomain() const {
return is_domain;
@@ -142,10 +152,18 @@ public:
session_handler = std::move(handler);
}
+ std::shared_ptr<ServiceThread> GetServiceThread() const {
+ return session_handler->GetServiceThread();
+ }
+
private:
bool is_domain{};
SessionRequestHandlerPtr session_handler;
std::vector<SessionRequestHandlerPtr> domain_handlers;
+
+private:
+ KernelCore& kernel;
+ std::weak_ptr<ServiceThread> service_thread;
};
/**
diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h
index bc18582be..88a052f65 100644
--- a/src/core/hle/kernel/k_auto_object.h
+++ b/src/core/hle/kernel/k_auto_object.h
@@ -7,10 +7,11 @@
#include <atomic>
#include <string>
+#include <boost/intrusive/rbtree.hpp>
+
#include "common/assert.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
-#include "common/intrusive_red_black_tree.h"
#include "core/hle/kernel/k_class_token.h"
namespace Kernel {
@@ -175,7 +176,7 @@ private:
class KAutoObjectWithListContainer;
-class KAutoObjectWithList : public KAutoObject {
+class KAutoObjectWithList : public KAutoObject, public boost::intrusive::set_base_hook<> {
public:
explicit KAutoObjectWithList(KernelCore& kernel_) : KAutoObject(kernel_) {}
@@ -192,6 +193,10 @@ public:
}
}
+ friend bool operator<(const KAutoObjectWithList& left, const KAutoObjectWithList& right) {
+ return &left < &right;
+ }
+
public:
virtual u64 GetId() const {
return reinterpret_cast<u64>(this);
@@ -203,8 +208,6 @@ public:
private:
friend class KAutoObjectWithListContainer;
-
- Common::IntrusiveRedBlackTreeNode list_node;
};
template <typename T>
diff --git a/src/core/hle/kernel/k_auto_object_container.cpp b/src/core/hle/kernel/k_auto_object_container.cpp
index fc0c28874..010006bb7 100644
--- a/src/core/hle/kernel/k_auto_object_container.cpp
+++ b/src/core/hle/kernel/k_auto_object_container.cpp
@@ -9,13 +9,13 @@ namespace Kernel {
void KAutoObjectWithListContainer::Register(KAutoObjectWithList* obj) {
KScopedLightLock lk(m_lock);
- m_object_list.insert(*obj);
+ m_object_list.insert_unique(*obj);
}
void KAutoObjectWithListContainer::Unregister(KAutoObjectWithList* obj) {
KScopedLightLock lk(m_lock);
- m_object_list.erase(m_object_list.iterator_to(*obj));
+ m_object_list.erase(*obj);
}
size_t KAutoObjectWithListContainer::GetOwnedCount(KProcess* owner) {
diff --git a/src/core/hle/kernel/k_auto_object_container.h b/src/core/hle/kernel/k_auto_object_container.h
index ff40cf5a7..459953450 100644
--- a/src/core/hle/kernel/k_auto_object_container.h
+++ b/src/core/hle/kernel/k_auto_object_container.h
@@ -6,6 +6,8 @@
#include <atomic>
+#include <boost/intrusive/rbtree.hpp>
+
#include "common/assert.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
@@ -23,8 +25,7 @@ class KAutoObjectWithListContainer {
YUZU_NON_MOVEABLE(KAutoObjectWithListContainer);
public:
- using ListType = Common::IntrusiveRedBlackTreeMemberTraits<
- &KAutoObjectWithList::list_node>::TreeType<KAutoObjectWithList>;
+ using ListType = boost::intrusive::rbtree<KAutoObjectWithList>;
public:
class ListAccessor : public KScopedLightLock {
diff --git a/src/core/hle/kernel/k_client_port.cpp b/src/core/hle/kernel/k_client_port.cpp
index 23d830d1f..50606bd91 100644
--- a/src/core/hle/kernel/k_client_port.cpp
+++ b/src/core/hle/kernel/k_client_port.cpp
@@ -16,11 +16,11 @@ namespace Kernel {
KClientPort::KClientPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {}
KClientPort::~KClientPort() = default;
-void KClientPort::Initialize(KPort* parent_, s32 max_sessions_, std::string&& name_) {
+void KClientPort::Initialize(KPort* parent_port_, s32 max_sessions_, std::string&& name_) {
// Set member variables.
num_sessions = 0;
peak_sessions = 0;
- parent = parent_;
+ parent = parent_port_;
max_sessions = max_sessions_;
name = std::move(name_);
}
@@ -56,7 +56,8 @@ bool KClientPort::IsSignaled() const {
return num_sessions < max_sessions;
}
-ResultCode KClientPort::CreateSession(KClientSession** out) {
+ResultCode KClientPort::CreateSession(KClientSession** out,
+ std::shared_ptr<SessionRequestManager> session_manager) {
// Reserve a new session from the resource limit.
KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(),
LimitableResource::Sessions);
@@ -101,7 +102,7 @@ ResultCode KClientPort::CreateSession(KClientSession** out) {
}
// Initialize the session.
- session->Initialize(this, parent->GetName());
+ session->Initialize(this, parent->GetName(), session_manager);
// Commit the session reservation.
session_reservation.Commit();
diff --git a/src/core/hle/kernel/k_client_port.h b/src/core/hle/kernel/k_client_port.h
index f2fff3b01..54bb05e20 100644
--- a/src/core/hle/kernel/k_client_port.h
+++ b/src/core/hle/kernel/k_client_port.h
@@ -16,6 +16,7 @@ namespace Kernel {
class KClientSession;
class KernelCore;
class KPort;
+class SessionRequestManager;
class KClientPort final : public KSynchronizationObject {
KERNEL_AUTOOBJECT_TRAITS(KClientPort, KSynchronizationObject);
@@ -52,7 +53,8 @@ public:
void Destroy() override;
bool IsSignaled() const override;
- ResultCode CreateSession(KClientSession** out);
+ ResultCode CreateSession(KClientSession** out,
+ std::shared_ptr<SessionRequestManager> session_manager = nullptr);
private:
std::atomic<s32> num_sessions{};
diff --git a/src/core/hle/kernel/k_client_session.h b/src/core/hle/kernel/k_client_session.h
index b11d5b4e3..230e3b6b8 100644
--- a/src/core/hle/kernel/k_client_session.h
+++ b/src/core/hle/kernel/k_client_session.h
@@ -36,9 +36,9 @@ public:
explicit KClientSession(KernelCore& kernel_);
~KClientSession() override;
- void Initialize(KSession* parent_, std::string&& name_) {
+ void Initialize(KSession* parent_session_, std::string&& name_) {
// Set member variables.
- parent = parent_;
+ parent = parent_session_;
name = std::move(name_);
}
diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h
index b2850ac7b..149fa78dd 100644
--- a/src/core/hle/kernel/k_readable_event.h
+++ b/src/core/hle/kernel/k_readable_event.h
@@ -21,9 +21,9 @@ public:
explicit KReadableEvent(KernelCore& kernel_);
~KReadableEvent() override;
- void Initialize(KEvent* parent_, std::string&& name_) {
+ void Initialize(KEvent* parent_event_, std::string&& name_) {
is_signaled = false;
- parent = parent_;
+ parent = parent_event_;
name = std::move(name_);
}
diff --git a/src/core/hle/kernel/k_server_port.cpp b/src/core/hle/kernel/k_server_port.cpp
index 8cbde177a..c5dc58387 100644
--- a/src/core/hle/kernel/k_server_port.cpp
+++ b/src/core/hle/kernel/k_server_port.cpp
@@ -17,9 +17,9 @@ namespace Kernel {
KServerPort::KServerPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {}
KServerPort::~KServerPort() = default;
-void KServerPort::Initialize(KPort* parent_, std::string&& name_) {
+void KServerPort::Initialize(KPort* parent_port_, std::string&& name_) {
// Set member variables.
- parent = parent_;
+ parent = parent_port_;
name = std::move(name_);
}
diff --git a/src/core/hle/kernel/k_server_port.h b/src/core/hle/kernel/k_server_port.h
index 55481d63f..67a36da40 100644
--- a/src/core/hle/kernel/k_server_port.h
+++ b/src/core/hle/kernel/k_server_port.h
@@ -29,7 +29,7 @@ public:
explicit KServerPort(KernelCore& kernel_);
~KServerPort() override;
- void Initialize(KPort* parent_, std::string&& name_);
+ void Initialize(KPort* parent_port_, std::string&& name_);
/// Whether or not this server port has an HLE handler available.
bool HasSessionRequestHandler() const {
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp
index dbf03b462..528ca8614 100644
--- a/src/core/hle/kernel/k_server_session.cpp
+++ b/src/core/hle/kernel/k_server_session.cpp
@@ -13,8 +13,10 @@
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_client_port.h"
#include "core/hle/kernel/k_handle_table.h"
+#include "core/hle/kernel/k_port.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_scheduler.h"
+#include "core/hle/kernel/k_server_port.h"
#include "core/hle/kernel/k_server_session.h"
#include "core/hle/kernel/k_session.h"
#include "core/hle/kernel/k_thread.h"
@@ -23,18 +25,21 @@
namespace Kernel {
-KServerSession::KServerSession(KernelCore& kernel_)
- : KSynchronizationObject{kernel_}, manager{std::make_shared<SessionRequestManager>()} {}
+KServerSession::KServerSession(KernelCore& kernel_) : KSynchronizationObject{kernel_} {}
-KServerSession::~KServerSession() {
- kernel.ReleaseServiceThread(service_thread);
-}
+KServerSession::~KServerSession() {}
-void KServerSession::Initialize(KSession* parent_, std::string&& name_) {
+void KServerSession::Initialize(KSession* parent_session_, std::string&& name_,
+ std::shared_ptr<SessionRequestManager> manager_) {
// Set member variables.
- parent = parent_;
+ parent = parent_session_;
name = std::move(name_);
- service_thread = kernel.CreateServiceThread(name);
+
+ if (manager_) {
+ manager = manager_;
+ } else {
+ manager = std::make_shared<SessionRequestManager>(kernel);
+ }
}
void KServerSession::Destroy() {
@@ -114,9 +119,11 @@ ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memor
context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
- if (auto strong_ptr = service_thread.lock()) {
+ if (auto strong_ptr = manager->GetServiceThread(); strong_ptr) {
strong_ptr->QueueSyncRequest(*parent, std::move(context));
return ResultSuccess;
+ } else {
+ ASSERT_MSG(false, "strong_ptr was nullptr!");
}
return ResultSuccess;
diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h
index 27b757ad2..9efd400bc 100644
--- a/src/core/hle/kernel/k_server_session.h
+++ b/src/core/hle/kernel/k_server_session.h
@@ -32,6 +32,7 @@ class HLERequestContext;
class KernelCore;
class KSession;
class SessionRequestHandler;
+class SessionRequestManager;
class KThread;
class KServerSession final : public KSynchronizationObject,
@@ -46,7 +47,8 @@ public:
void Destroy() override;
- void Initialize(KSession* parent_, std::string&& name_);
+ void Initialize(KSession* parent_session_, std::string&& name_,
+ std::shared_ptr<SessionRequestManager> manager_);
KSession* GetParent() {
return parent;
@@ -104,16 +106,6 @@ public:
return manager;
}
- /// Gets the session request manager, which forwards requests to the underlying service
- const std::shared_ptr<SessionRequestManager>& GetSessionRequestManager() const {
- return manager;
- }
-
- /// Sets the session request manager, which forwards requests to the underlying service
- void SetSessionRequestManager(std::shared_ptr<SessionRequestManager> manager_) {
- manager = std::move(manager_);
- }
-
private:
/// Queues a sync request from the emulated application.
ResultCode QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory);
@@ -131,9 +123,6 @@ private:
/// When set to True, converts the session to a domain at the end of the command
bool convert_to_domain{};
- /// Thread to dispatch service requests
- std::weak_ptr<ServiceThread> service_thread;
-
/// KSession that owns this KServerSession
KSession* parent{};
};
diff --git a/src/core/hle/kernel/k_session.cpp b/src/core/hle/kernel/k_session.cpp
index 025b8b555..940878e03 100644
--- a/src/core/hle/kernel/k_session.cpp
+++ b/src/core/hle/kernel/k_session.cpp
@@ -15,7 +15,8 @@ KSession::KSession(KernelCore& kernel_)
: KAutoObjectWithSlabHeapAndContainer{kernel_}, server{kernel_}, client{kernel_} {}
KSession::~KSession() = default;
-void KSession::Initialize(KClientPort* port_, const std::string& name_) {
+void KSession::Initialize(KClientPort* port_, const std::string& name_,
+ std::shared_ptr<SessionRequestManager> manager_) {
// Increment reference count.
// Because reference count is one on creation, this will result
// in a reference count of two. Thus, when both server and client are closed
@@ -27,7 +28,7 @@ void KSession::Initialize(KClientPort* port_, const std::string& name_) {
KAutoObject::Create(std::addressof(client));
// Initialize our sub sessions.
- server.Initialize(this, name_ + ":Server");
+ server.Initialize(this, name_ + ":Server", manager_);
client.Initialize(this, name_ + ":Client");
// Set state and name.
diff --git a/src/core/hle/kernel/k_session.h b/src/core/hle/kernel/k_session.h
index 4ddd080d2..62c328a68 100644
--- a/src/core/hle/kernel/k_session.h
+++ b/src/core/hle/kernel/k_session.h
@@ -13,6 +13,8 @@
namespace Kernel {
+class SessionRequestManager;
+
class KSession final : public KAutoObjectWithSlabHeapAndContainer<KSession, KAutoObjectWithList> {
KERNEL_AUTOOBJECT_TRAITS(KSession, KAutoObject);
@@ -20,7 +22,8 @@ public:
explicit KSession(KernelCore& kernel_);
~KSession() override;
- void Initialize(KClientPort* port_, const std::string& name_);
+ void Initialize(KClientPort* port_, const std::string& name_,
+ std::shared_ptr<SessionRequestManager> manager_ = nullptr);
void Finalize() override;
diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp
index b7b83c151..bdb1db6d5 100644
--- a/src/core/hle/kernel/k_writable_event.cpp
+++ b/src/core/hle/kernel/k_writable_event.cpp
@@ -13,8 +13,8 @@ KWritableEvent::KWritableEvent(KernelCore& kernel_)
KWritableEvent::~KWritableEvent() = default;
-void KWritableEvent::Initialize(KEvent* parent_, std::string&& name_) {
- parent = parent_;
+void KWritableEvent::Initialize(KEvent* parent_event_, std::string&& name_) {
+ parent = parent_event_;
name = std::move(name_);
parent->GetReadableEvent().Open();
}
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index 605236552..a755008d5 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -124,21 +124,21 @@ union ResultCode {
constexpr ResultCode(ErrorModule module_, u32 description_)
: raw(module.FormatValue(module_) | description.FormatValue(description_)) {}
- constexpr bool IsSuccess() const {
+ [[nodiscard]] constexpr bool IsSuccess() const {
return raw == 0;
}
- constexpr bool IsError() const {
- return raw != 0;
+ [[nodiscard]] constexpr bool IsError() const {
+ return !IsSuccess();
}
};
-constexpr bool operator==(const ResultCode& a, const ResultCode& b) {
+[[nodiscard]] constexpr bool operator==(const ResultCode& a, const ResultCode& b) {
return a.raw == b.raw;
}
-constexpr bool operator!=(const ResultCode& a, const ResultCode& b) {
- return a.raw != b.raw;
+[[nodiscard]] constexpr bool operator!=(const ResultCode& a, const ResultCode& b) {
+ return !operator==(a, b);
}
// Convenience functions for creating some common kinds of errors:
@@ -200,7 +200,7 @@ public:
* specify the success code. `success_code` must not be an error code.
*/
template <typename... Args>
- static ResultVal WithCode(ResultCode success_code, Args&&... args) {
+ [[nodiscard]] static ResultVal WithCode(ResultCode success_code, Args&&... args) {
ResultVal<T> result;
result.emplace(success_code, std::forward<Args>(args)...);
return result;
@@ -259,49 +259,49 @@ public:
}
/// Returns true if the `ResultVal` contains an error code and no value.
- bool empty() const {
+ [[nodiscard]] bool empty() const {
return result_code.IsError();
}
/// Returns true if the `ResultVal` contains a return value.
- bool Succeeded() const {
+ [[nodiscard]] bool Succeeded() const {
return result_code.IsSuccess();
}
/// Returns true if the `ResultVal` contains an error code and no value.
- bool Failed() const {
+ [[nodiscard]] bool Failed() const {
return empty();
}
- ResultCode Code() const {
+ [[nodiscard]] ResultCode Code() const {
return result_code;
}
- const T& operator*() const {
+ [[nodiscard]] const T& operator*() const {
return object;
}
- T& operator*() {
+ [[nodiscard]] T& operator*() {
return object;
}
- const T* operator->() const {
+ [[nodiscard]] const T* operator->() const {
return &object;
}
- T* operator->() {
+ [[nodiscard]] T* operator->() {
return &object;
}
/// Returns the value contained in this `ResultVal`, or the supplied default if it is missing.
template <typename U>
- T ValueOr(U&& value) const {
+ [[nodiscard]] T ValueOr(U&& value) const {
return !empty() ? object : std::move(value);
}
/// Asserts that the result succeeded and returns a reference to it.
- T& Unwrap() & {
+ [[nodiscard]] T& Unwrap() & {
ASSERT_MSG(Succeeded(), "Tried to Unwrap empty ResultVal");
return **this;
}
- T&& Unwrap() && {
+ [[nodiscard]] T&& Unwrap() && {
ASSERT_MSG(Succeeded(), "Tried to Unwrap empty ResultVal");
return std::move(**this);
}
@@ -320,7 +320,7 @@ private:
* `T` with and creates a success `ResultVal` contained the constructed value.
*/
template <typename T, typename... Args>
-ResultVal<T> MakeResult(Args&&... args) {
+[[nodiscard]] ResultVal<T> MakeResult(Args&&... args) {
return ResultVal<T>::WithCode(ResultSuccess, std::forward<Args>(args)...);
}
@@ -329,7 +329,7 @@ ResultVal<T> MakeResult(Args&&... args) {
* copy or move constructing.
*/
template <typename Arg>
-ResultVal<std::remove_reference_t<Arg>> MakeResult(Arg&& arg) {
+[[nodiscard]] ResultVal<std::remove_reference_t<Arg>> MakeResult(Arg&& arg) {
return ResultVal<std::remove_reference_t<Arg>>::WithCode(ResultSuccess, std::forward<Arg>(arg));
}
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index 6e5ba26a3..74cc45f1e 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -254,8 +254,6 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_NS, "called");
// Create shared font memory object
- auto& kernel = system.Kernel();
-
std::memcpy(kernel.GetFontSharedMem().GetPointer(), impl->shared_font->data(),
impl->shared_font->size());
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 7a15eeba0..4e1541630 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -93,8 +93,8 @@ namespace Service {
ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_,
u32 max_sessions_, InvokerFn* handler_invoker_)
- : system{system_}, service_name{service_name_}, max_sessions{max_sessions_},
- handler_invoker{handler_invoker_} {}
+ : SessionRequestHandler(system_.Kernel(), service_name_), system{system_},
+ service_name{service_name_}, max_sessions{max_sessions_}, handler_invoker{handler_invoker_} {}
ServiceFrameworkBase::~ServiceFrameworkBase() {
// Wait for other threads to release access before destroying
@@ -111,7 +111,7 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager)
port_installed = true;
}
-Kernel::KClientPort& ServiceFrameworkBase::CreatePort(Kernel::KernelCore& kernel) {
+Kernel::KClientPort& ServiceFrameworkBase::CreatePort() {
const auto guard = LockService();
ASSERT(!port_installed);
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 4c048173b..ec757753c 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -23,6 +23,7 @@ namespace Kernel {
class HLERequestContext;
class KClientPort;
class KServerSession;
+class ServiceThread;
} // namespace Kernel
namespace Service {
@@ -41,7 +42,7 @@ class ServiceManager;
static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters)
/// Arbitrary default number of maximum connections to an HLE service.
-static const u32 DefaultMaxSessions = 10;
+static const u32 DefaultMaxSessions = 64;
/**
* This is an non-templated base of ServiceFramework to reduce code bloat and compilation times, it
@@ -74,7 +75,7 @@ public:
void InvokeRequestTipc(Kernel::HLERequestContext& ctx);
/// Creates a port pair and registers it on the kernel's global port registry.
- Kernel::KClientPort& CreatePort(Kernel::KernelCore& kernel);
+ Kernel::KClientPort& CreatePort();
/// Handles a synchronization request for the service.
ResultCode HandleSyncRequest(Kernel::KServerSession& session,
diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp
index 5fa5e0512..8b9418e0f 100644
--- a/src/core/hle/service/sm/controller.cpp
+++ b/src/core/hle/service/sm/controller.cpp
@@ -28,42 +28,25 @@ void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) {
}
void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
- // TODO(bunnei): This is just creating a new handle to the same Session. I assume this is wrong
- // and that we probably want to actually make an entirely new Session, but we still need to
- // verify this on hardware.
-
LOG_DEBUG(Service, "called");
- auto& kernel = system.Kernel();
- auto* session = ctx.Session()->GetParent();
- auto* port = session->GetParent()->GetParent();
+ auto& parent_session = *ctx.Session()->GetParent();
+ auto& parent_port = parent_session.GetParent()->GetParent()->GetClientPort();
+ auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager();
- // Reserve a new session from the process resource limit.
- Kernel::KScopedResourceReservation session_reservation(
- kernel.CurrentProcess()->GetResourceLimit(), Kernel::LimitableResource::Sessions);
- if (!session_reservation.Succeeded()) {
+ // Create a session.
+ Kernel::KClientSession* session{};
+ const ResultCode result = parent_port.CreateSession(std::addressof(session), session_manager);
+ if (result.IsError()) {
+ LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(Kernel::ResultLimitReached);
+ rb.Push(result);
}
- // Create a new session.
- auto* clone = Kernel::KSession::Create(kernel);
- clone->Initialize(&port->GetClientPort(), session->GetName());
-
- // Commit the session reservation.
- session_reservation.Commit();
-
- // Enqueue the session with the named port.
- port->EnqueueSession(&clone->GetServerSession());
-
- // Set the session request manager.
- clone->GetServerSession().SetSessionRequestManager(
- session->GetServerSession().GetSessionRequestManager());
-
// We succeeded.
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
rb.Push(ResultSuccess);
- rb.PushMoveObjects(clone->GetClientSession());
+ rb.PushMoveObjects(session);
}
void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index d8b20a3f2..bffa9ffcb 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -46,7 +46,7 @@ Kernel::KClientPort& ServiceManager::InterfaceFactory(ServiceManager& self, Core
self.sm_interface = sm;
self.controller_interface = std::make_unique<Controller>(system);
- return sm->CreatePort(system.Kernel());
+ return sm->CreatePort();
}
ResultVal<Kernel::KServerPort*> ServiceManager::RegisterService(std::string name,