From 13c26b43719977cc18b6f4a913b63142637514be Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Sat, 13 Oct 2018 16:11:20 -0400 Subject: [PATCH] Kernel: pass ref to session pair --- src/core/core.cpp | 2 +- src/core/hle/kernel/client_port.cpp | 4 ++-- src/core/hle/kernel/client_port.h | 1 + src/core/hle/kernel/client_session.cpp | 2 +- src/core/hle/kernel/client_session.h | 5 ++--- src/core/hle/kernel/kernel.h | 11 +++++++++++ src/core/hle/kernel/server_session.cpp | 14 +++++++------- src/core/hle/kernel/server_session.h | 19 ++++++------------- src/core/hle/kernel/svc.cpp | 2 +- src/core/hle/service/am/am.cpp | 10 +++++----- src/core/hle/service/am/am.h | 1 + src/core/hle/service/fs/archive.cpp | 4 ++-- src/core/hle/service/fs/archive.h | 9 ++++++++- src/core/hle/service/fs/file.cpp | 12 +++++++----- src/core/hle/service/fs/file.h | 9 ++++++++- src/core/hle/service/fs/fs_user.cpp | 7 ++++--- src/core/hle/service/fs/fs_user.h | 3 ++- src/tests/core/hle/kernel/hle_ipc.cpp | 4 ++-- 18 files changed, 71 insertions(+), 48 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 6212347e2..4d4379299 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -193,7 +193,7 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) { service_manager = std::make_shared(*this); shared_page_handler = std::make_shared(); - archive_manager = std::make_unique(); + archive_manager = std::make_unique(*this); HW::Init(); kernel = std::make_unique(system_mode); diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index f70b84ae2..bfbfc3720 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -13,7 +13,7 @@ namespace Kernel { -ClientPort::ClientPort(KernelSystem& kernel) {} +ClientPort::ClientPort(KernelSystem& kernel) : kernel(kernel) {} ClientPort::~ClientPort() = default; ResultVal> ClientPort::Connect() { @@ -26,7 +26,7 @@ ResultVal> ClientPort::Connect() { active_sessions++; // Create a new session pair, let the created sessions inherit the parent port's HLE handler. - auto sessions = ServerSession::CreateSessionPair(server_port->GetName(), this); + auto sessions = kernel.CreateSessionPair(server_port->GetName(), this); if (server_port->hle_handler) server_port->hle_handler->ClientConnected(std::get>(sessions)); diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 2dda05f15..149ca77a1 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -51,6 +51,7 @@ private: explicit ClientPort(KernelSystem& kernel); ~ClientPort() override; + KernelSystem& kernel; SharedPtr server_port; ///< ServerPort associated with this client port. u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have u32 active_sessions = 0; ///< Number of currently open sessions to this port diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index 17f4c12d3..c2c3634ba 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp @@ -13,7 +13,7 @@ namespace Kernel { -ClientSession::ClientSession() = default; +ClientSession::ClientSession(KernelSystem& kernel) {} ClientSession::~ClientSession() { // This destructor will be called automatically when the last ClientSession handle is closed by // the emulated application. diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index 9c6b47927..5d5a2d9cd 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -12,13 +12,12 @@ namespace Kernel { -class ServerSession; class Session; class Thread; class ClientSession final : public Object { public: - friend class ServerSession; + friend class KernelSystem; std::string GetTypeName() const override { return "ClientSession"; @@ -46,7 +45,7 @@ public: std::shared_ptr parent; private: - ClientSession(); + explicit ClientSession(KernelSystem& kernel); ~ClientSession() override; }; diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 79b939c07..9ff8504e0 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -21,6 +21,8 @@ class Semaphore; class Timer; class ClientPort; class ServerPort; +class ClientSession; +class ServerSession; enum class ResetType { OneShot, @@ -105,6 +107,15 @@ public: */ std::tuple, SharedPtr> CreatePortPair( u32 max_sessions, std::string name = "UnknownPort"); + + /** + * Creates a pair of ServerSession and an associated ClientSession. + * @param name Optional name of the ports. + * @param client_port Optional The ClientPort that spawned this session. + * @return The created session tuple + */ + std::tuple, SharedPtr> CreateSessionPair( + const std::string& name = "Unknown", SharedPtr client_port = nullptr); }; } // namespace Kernel diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 71f702b9e..3382abae3 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -13,7 +13,7 @@ namespace Kernel { -ServerSession::ServerSession() = default; +ServerSession::ServerSession(KernelSystem& kernel) {} ServerSession::~ServerSession() { // This destructor will be called automatically when the last ServerSession handle is closed by // the emulated application. @@ -28,8 +28,8 @@ ServerSession::~ServerSession() { parent->server = nullptr; } -ResultVal> ServerSession::Create(std::string name) { - SharedPtr server_session(new ServerSession); +ResultVal> ServerSession::Create(KernelSystem& kernel, std::string name) { + SharedPtr server_session(new ServerSession(kernel)); server_session->name = std::move(name); server_session->parent = nullptr; @@ -100,10 +100,10 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr thread) { return RESULT_SUCCESS; } -ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, - SharedPtr port) { - auto server_session = ServerSession::Create(name + "_Server").Unwrap(); - SharedPtr client_session(new ClientSession); +std::tuple, SharedPtr> KernelSystem::CreateSessionPair( + const std::string& name, SharedPtr port) { + auto server_session = ServerSession::Create(*this, name + "_Server").Unwrap(); + SharedPtr client_session(new ClientSession(*this)); client_session->name = name + "_Client"; std::shared_ptr parent(new Session); diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index c739bae5e..18411e417 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -48,17 +48,6 @@ public: return HANDLE_TYPE; } - using SessionPair = std::tuple, SharedPtr>; - - /** - * Creates a pair of ServerSession and an associated ClientSession. - * @param name Optional name of the ports. - * @param client_port Optional The ClientPort that spawned this session. - * @return The created session tuple - */ - static SessionPair CreateSessionPair(const std::string& name = "Unknown", - SharedPtr client_port = nullptr); - /** * Sets the HLE handler for the session. This handler will be called to service IPC requests * instead of the regular IPC machinery. (The regular IPC machinery is currently not @@ -95,16 +84,20 @@ public: SharedPtr currently_handling; private: - ServerSession(); + explicit ServerSession(KernelSystem& kernel); ~ServerSession() override; /** * Creates a server session. The server session can have an optional HLE handler, * which will be invoked to handle the IPC requests that this session receives. + * @param kernel The kernel instance to create the server session on * @param name Optional name of the server session. * @return The created server session */ - static ResultVal> Create(std::string name = "Unknown"); + static ResultVal> Create(KernelSystem& kernel, + std::string name = "Unknown"); + + friend class KernelSystem; }; } // namespace Kernel diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 0c2e0c160..632d2e539 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1142,7 +1142,7 @@ static ResultCode CreateSessionToPort(Handle* out_client_session, Handle client_ } static ResultCode CreateSession(Handle* server_session, Handle* client_session) { - auto sessions = ServerSession::CreateSessionPair(); + auto sessions = Core::System::GetInstance().Kernel().CreateSessionPair(); auto& server = std::get>(sessions); CASCADE_RESULT(*server_session, g_handle_table.Create(std::move(server))); diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index e9f0c6227..972c826a9 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1026,8 +1026,8 @@ void Module::Interface::BeginImportProgram(Kernel::HLERequestContext& ctx) { // Create our CIAFile handle for the app to write to, and while the app writes // Citra will store contents out to sdmc/nand const FileSys::Path cia_path = {}; - auto file = - std::make_shared(std::make_unique(media_type), cia_path); + auto file = std::make_shared( + am->system, std::make_unique(media_type), cia_path); am->cia_installing = true; @@ -1053,8 +1053,8 @@ void Module::Interface::BeginImportProgramTemporarily(Kernel::HLERequestContext& // Create our CIAFile handle for the app to write to, and while the app writes Citra will store // contents out to sdmc/nand const FileSys::Path cia_path = {}; - auto file = std::make_shared(std::make_unique(FS::MediaType::NAND), - cia_path); + auto file = std::make_shared( + am->system, std::make_unique(FS::MediaType::NAND), cia_path); am->cia_installing = true; @@ -1455,7 +1455,7 @@ void Module::Interface::GetMetaDataFromCia(Kernel::HLERequestContext& ctx) { rb.PushMappedBuffer(output_buffer); } -Module::Module(Core::System& system) { +Module::Module(Core::System& system) : system(system) { ScanForAllTitles(); system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex"); } diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 792225113..e00e16abd 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -573,6 +573,7 @@ private: */ void ScanForAllTitles(); + Core::System& system; bool cia_installing = false; std::array, 3> am_title_list; Kernel::SharedPtr system_updater_mutex; diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 0f2375124..4322f6653 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -87,7 +87,7 @@ ResultVal> ArchiveManager::OpenFileFromArchive(ArchiveHand if (backend.Failed()) return backend.Code(); - auto file = std::shared_ptr(new File(std::move(backend).Unwrap(), path)); + auto file = std::shared_ptr(new File(system, std::move(backend).Unwrap(), path)); return MakeResult>(std::move(file)); } @@ -348,7 +348,7 @@ void ArchiveManager::RegisterSelfNCCH(Loader::AppLoader& app_loader) { factory->Register(app_loader); } -ArchiveManager::ArchiveManager() { +ArchiveManager::ArchiveManager(Core::System& system) : system(system) { RegisterArchiveTypes(); } diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index ef9b9efc2..f335f650d 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -24,6 +24,10 @@ namespace Loader { class AppLoader; } +namespace Core { +class System; +} + namespace Service::FS { /// Supported archive types @@ -50,7 +54,8 @@ using FileSys::ArchiveFactory; class ArchiveManager { public: - ArchiveManager(); + explicit ArchiveManager(Core::System& system); + /** * Opens an archive * @param id_code IdCode of the archive to open @@ -224,6 +229,8 @@ public: void RegisterSelfNCCH(Loader::AppLoader& app_loader); private: + Core::System& system; + /** * Registers an Archive type, instances of which can later be opened using its IdCode. * @param factory File system backend interface to the archive diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index d2f1f2a85..59635cab8 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "common/logging/log.h" +#include "core/core.h" #include "core/file_sys/errors.h" #include "core/file_sys/file_backend.h" #include "core/hle/ipc_helpers.h" @@ -14,8 +15,9 @@ namespace Service::FS { -File::File(std::unique_ptr&& backend, const FileSys::Path& path) - : ServiceFramework("", 1), path(path), backend(std::move(backend)) { +File::File(Core::System& system, std::unique_ptr&& backend, + const FileSys::Path& path) + : ServiceFramework("", 1), path(path), backend(std::move(backend)), system(system) { static const FunctionInfo functions[] = { {0x08010100, &File::OpenSubFile, "OpenSubFile"}, {0x080200C2, &File::Read, "Read"}, @@ -195,7 +197,7 @@ void File::OpenLinkFile(Kernel::HLERequestContext& ctx) { using Kernel::SharedPtr; IPC::RequestParser rp(ctx, 0x080C, 0, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); - auto sessions = ServerSession::CreateSessionPair(GetName()); + auto sessions = system.Kernel().CreateSessionPair(GetName()); auto server = std::get>(sessions); ClientConnected(server); @@ -243,7 +245,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) { using Kernel::ClientSession; using Kernel::ServerSession; using Kernel::SharedPtr; - auto sessions = ServerSession::CreateSessionPair(GetName()); + auto sessions = system.Kernel().CreateSessionPair(GetName()); auto server = std::get>(sessions); ClientConnected(server); @@ -258,7 +260,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) { } Kernel::SharedPtr File::Connect() { - auto sessions = Kernel::ServerSession::CreateSessionPair(GetName()); + auto sessions = system.Kernel().CreateSessionPair(GetName()); auto server = std::get>(sessions); ClientConnected(server); diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index 2de9add98..b946491b8 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -8,6 +8,10 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/service/service.h" +namespace Core { +class System; +} + namespace Service::FS { struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase { @@ -21,7 +25,8 @@ struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase { // Consider splitting ServiceFramework interface. class File final : public ServiceFramework { public: - File(std::unique_ptr&& backend, const FileSys::Path& path); + File(Core::System& system, std::unique_ptr&& backend, + const FileSys::Path& path); ~File() = default; std::string GetName() const { @@ -53,6 +58,8 @@ private: void GetPriority(Kernel::HLERequestContext& ctx); void OpenLinkFile(Kernel::HLERequestContext& ctx); void OpenSubFile(Kernel::HLERequestContext& ctx); + + Core::System& system; }; } // namespace Service::FS diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index e4a7c251d..7b1316e48 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -286,7 +286,7 @@ void FS_USER::OpenDirectory(Kernel::HLERequestContext& ctx) { rb.Push(dir_res.Code()); if (dir_res.Succeeded()) { std::shared_ptr directory = *dir_res; - auto sessions = ServerSession::CreateSessionPair(directory->GetName()); + auto sessions = system.Kernel().CreateSessionPair(directory->GetName()); directory->ClientConnected(std::get>(sessions)); rb.PushMoveObjects(std::get>(sessions)); } else { @@ -741,7 +741,8 @@ void FS_USER::GetSaveDataSecureValue(Kernel::HLERequestContext& ctx) { rb.Push(0); // the secure value } -FS_USER::FS_USER(ArchiveManager& archives) : ServiceFramework("fs:USER", 30), archives(archives) { +FS_USER::FS_USER(Core::System& system) + : ServiceFramework("fs:USER", 30), system(system), archives(system.ArchiveManager()) { static const FunctionInfo functions[] = { {0x000100C6, nullptr, "Dummy1"}, {0x040100C4, nullptr, "Control"}, @@ -860,6 +861,6 @@ FS_USER::FS_USER(ArchiveManager& archives) : ServiceFramework("fs:USER", 30), ar void InstallInterfaces(Core::System& system) { auto& service_manager = system.ServiceManager(); - std::make_shared(system.ArchiveManager())->InstallAsService(service_manager); + std::make_shared(system)->InstallAsService(service_manager); } } // namespace Service::FS diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index eb1b5af36..90c0ed7ec 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -17,7 +17,7 @@ class ArchiveManager; class FS_USER final : public ServiceFramework { public: - explicit FS_USER(ArchiveManager& archives); + explicit FS_USER(Core::System& system); private: void Initialize(Kernel::HLERequestContext& ctx); @@ -534,6 +534,7 @@ private: u32 priority = -1; ///< For SetPriority and GetPriority service functions + Core::System& system; ArchiveManager& archives; }; diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index bb4c3b6ad..9e093f4e4 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -22,7 +22,7 @@ static SharedPtr MakeObject(Kernel::KernelSystem& kernel) { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { CoreTiming::Init(); Kernel::KernelSystem kernel(0); - auto session = std::get>(ServerSession::CreateSessionPair()); + auto session = std::get>(kernel.CreateSessionPair()); HLERequestContext context(std::move(session)); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); @@ -232,7 +232,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { CoreTiming::Init(); Kernel::KernelSystem kernel(0); - auto session = std::get>(ServerSession::CreateSessionPair()); + auto session = std::get>(kernel.CreateSessionPair()); HLERequestContext context(std::move(session)); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));