Kernel: pass ref to session pair

This commit is contained in:
Weiyi Wang 2018-10-13 16:11:20 -04:00
parent 1213a298df
commit 13c26b4371
18 changed files with 71 additions and 48 deletions

View file

@ -193,7 +193,7 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) {
service_manager = std::make_shared<Service::SM::ServiceManager>(*this); service_manager = std::make_shared<Service::SM::ServiceManager>(*this);
shared_page_handler = std::make_shared<SharedPage::Handler>(); shared_page_handler = std::make_shared<SharedPage::Handler>();
archive_manager = std::make_unique<Service::FS::ArchiveManager>(); archive_manager = std::make_unique<Service::FS::ArchiveManager>(*this);
HW::Init(); HW::Init();
kernel = std::make_unique<Kernel::KernelSystem>(system_mode); kernel = std::make_unique<Kernel::KernelSystem>(system_mode);

View file

@ -13,7 +13,7 @@
namespace Kernel { namespace Kernel {
ClientPort::ClientPort(KernelSystem& kernel) {} ClientPort::ClientPort(KernelSystem& kernel) : kernel(kernel) {}
ClientPort::~ClientPort() = default; ClientPort::~ClientPort() = default;
ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
@ -26,7 +26,7 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
active_sessions++; active_sessions++;
// Create a new session pair, let the created sessions inherit the parent port's HLE handler. // 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) if (server_port->hle_handler)
server_port->hle_handler->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions)); server_port->hle_handler->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions));

View file

@ -51,6 +51,7 @@ private:
explicit ClientPort(KernelSystem& kernel); explicit ClientPort(KernelSystem& kernel);
~ClientPort() override; ~ClientPort() override;
KernelSystem& kernel;
SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have 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 u32 active_sessions = 0; ///< Number of currently open sessions to this port

View file

@ -13,7 +13,7 @@
namespace Kernel { namespace Kernel {
ClientSession::ClientSession() = default; ClientSession::ClientSession(KernelSystem& kernel) {}
ClientSession::~ClientSession() { ClientSession::~ClientSession() {
// This destructor will be called automatically when the last ClientSession handle is closed by // This destructor will be called automatically when the last ClientSession handle is closed by
// the emulated application. // the emulated application.

View file

@ -12,13 +12,12 @@
namespace Kernel { namespace Kernel {
class ServerSession;
class Session; class Session;
class Thread; class Thread;
class ClientSession final : public Object { class ClientSession final : public Object {
public: public:
friend class ServerSession; friend class KernelSystem;
std::string GetTypeName() const override { std::string GetTypeName() const override {
return "ClientSession"; return "ClientSession";
@ -46,7 +45,7 @@ public:
std::shared_ptr<Session> parent; std::shared_ptr<Session> parent;
private: private:
ClientSession(); explicit ClientSession(KernelSystem& kernel);
~ClientSession() override; ~ClientSession() override;
}; };

View file

@ -21,6 +21,8 @@ class Semaphore;
class Timer; class Timer;
class ClientPort; class ClientPort;
class ServerPort; class ServerPort;
class ClientSession;
class ServerSession;
enum class ResetType { enum class ResetType {
OneShot, OneShot,
@ -105,6 +107,15 @@ public:
*/ */
std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> CreatePortPair( std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> CreatePortPair(
u32 max_sessions, std::string name = "UnknownPort"); 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<ServerSession>, SharedPtr<ClientSession>> CreateSessionPair(
const std::string& name = "Unknown", SharedPtr<ClientPort> client_port = nullptr);
}; };
} // namespace Kernel } // namespace Kernel

View file

@ -13,7 +13,7 @@
namespace Kernel { namespace Kernel {
ServerSession::ServerSession() = default; ServerSession::ServerSession(KernelSystem& kernel) {}
ServerSession::~ServerSession() { ServerSession::~ServerSession() {
// This destructor will be called automatically when the last ServerSession handle is closed by // This destructor will be called automatically when the last ServerSession handle is closed by
// the emulated application. // the emulated application.
@ -28,8 +28,8 @@ ServerSession::~ServerSession() {
parent->server = nullptr; parent->server = nullptr;
} }
ResultVal<SharedPtr<ServerSession>> ServerSession::Create(std::string name) { ResultVal<SharedPtr<ServerSession>> ServerSession::Create(KernelSystem& kernel, std::string name) {
SharedPtr<ServerSession> server_session(new ServerSession); SharedPtr<ServerSession> server_session(new ServerSession(kernel));
server_session->name = std::move(name); server_session->name = std::move(name);
server_session->parent = nullptr; server_session->parent = nullptr;
@ -100,10 +100,10 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> KernelSystem::CreateSessionPair(
SharedPtr<ClientPort> port) { const std::string& name, SharedPtr<ClientPort> port) {
auto server_session = ServerSession::Create(name + "_Server").Unwrap(); auto server_session = ServerSession::Create(*this, name + "_Server").Unwrap();
SharedPtr<ClientSession> client_session(new ClientSession); SharedPtr<ClientSession> client_session(new ClientSession(*this));
client_session->name = name + "_Client"; client_session->name = name + "_Client";
std::shared_ptr<Session> parent(new Session); std::shared_ptr<Session> parent(new Session);

View file

@ -48,17 +48,6 @@ public:
return HANDLE_TYPE; return HANDLE_TYPE;
} }
using SessionPair = std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>>;
/**
* 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<ClientPort> client_port = nullptr);
/** /**
* Sets the HLE handler for the session. This handler will be called to service IPC requests * 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 * instead of the regular IPC machinery. (The regular IPC machinery is currently not
@ -95,16 +84,20 @@ public:
SharedPtr<Thread> currently_handling; SharedPtr<Thread> currently_handling;
private: private:
ServerSession(); explicit ServerSession(KernelSystem& kernel);
~ServerSession() override; ~ServerSession() override;
/** /**
* Creates a server session. The server session can have an optional HLE handler, * 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. * 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. * @param name Optional name of the server session.
* @return The created server session * @return The created server session
*/ */
static ResultVal<SharedPtr<ServerSession>> Create(std::string name = "Unknown"); static ResultVal<SharedPtr<ServerSession>> Create(KernelSystem& kernel,
std::string name = "Unknown");
friend class KernelSystem;
}; };
} // namespace Kernel } // namespace Kernel

View file

@ -1142,7 +1142,7 @@ static ResultCode CreateSessionToPort(Handle* out_client_session, Handle client_
} }
static ResultCode CreateSession(Handle* server_session, Handle* client_session) { static ResultCode CreateSession(Handle* server_session, Handle* client_session) {
auto sessions = ServerSession::CreateSessionPair(); auto sessions = Core::System::GetInstance().Kernel().CreateSessionPair();
auto& server = std::get<SharedPtr<ServerSession>>(sessions); auto& server = std::get<SharedPtr<ServerSession>>(sessions);
CASCADE_RESULT(*server_session, g_handle_table.Create(std::move(server))); CASCADE_RESULT(*server_session, g_handle_table.Create(std::move(server)));

View file

@ -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 // Create our CIAFile handle for the app to write to, and while the app writes
// Citra will store contents out to sdmc/nand // Citra will store contents out to sdmc/nand
const FileSys::Path cia_path = {}; const FileSys::Path cia_path = {};
auto file = auto file = std::make_shared<Service::FS::File>(
std::make_shared<Service::FS::File>(std::make_unique<CIAFile>(media_type), cia_path); am->system, std::make_unique<CIAFile>(media_type), cia_path);
am->cia_installing = true; 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 // Create our CIAFile handle for the app to write to, and while the app writes Citra will store
// contents out to sdmc/nand // contents out to sdmc/nand
const FileSys::Path cia_path = {}; const FileSys::Path cia_path = {};
auto file = std::make_shared<Service::FS::File>(std::make_unique<CIAFile>(FS::MediaType::NAND), auto file = std::make_shared<Service::FS::File>(
cia_path); am->system, std::make_unique<CIAFile>(FS::MediaType::NAND), cia_path);
am->cia_installing = true; am->cia_installing = true;
@ -1455,7 +1455,7 @@ void Module::Interface::GetMetaDataFromCia(Kernel::HLERequestContext& ctx) {
rb.PushMappedBuffer(output_buffer); rb.PushMappedBuffer(output_buffer);
} }
Module::Module(Core::System& system) { Module::Module(Core::System& system) : system(system) {
ScanForAllTitles(); ScanForAllTitles();
system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex"); system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex");
} }

View file

@ -573,6 +573,7 @@ private:
*/ */
void ScanForAllTitles(); void ScanForAllTitles();
Core::System& system;
bool cia_installing = false; bool cia_installing = false;
std::array<std::vector<u64_le>, 3> am_title_list; std::array<std::vector<u64_le>, 3> am_title_list;
Kernel::SharedPtr<Kernel::Mutex> system_updater_mutex; Kernel::SharedPtr<Kernel::Mutex> system_updater_mutex;

View file

@ -87,7 +87,7 @@ ResultVal<std::shared_ptr<File>> ArchiveManager::OpenFileFromArchive(ArchiveHand
if (backend.Failed()) if (backend.Failed())
return backend.Code(); return backend.Code();
auto file = std::shared_ptr<File>(new File(std::move(backend).Unwrap(), path)); auto file = std::shared_ptr<File>(new File(system, std::move(backend).Unwrap(), path));
return MakeResult<std::shared_ptr<File>>(std::move(file)); return MakeResult<std::shared_ptr<File>>(std::move(file));
} }
@ -348,7 +348,7 @@ void ArchiveManager::RegisterSelfNCCH(Loader::AppLoader& app_loader) {
factory->Register(app_loader); factory->Register(app_loader);
} }
ArchiveManager::ArchiveManager() { ArchiveManager::ArchiveManager(Core::System& system) : system(system) {
RegisterArchiveTypes(); RegisterArchiveTypes();
} }

View file

@ -24,6 +24,10 @@ namespace Loader {
class AppLoader; class AppLoader;
} }
namespace Core {
class System;
}
namespace Service::FS { namespace Service::FS {
/// Supported archive types /// Supported archive types
@ -50,7 +54,8 @@ using FileSys::ArchiveFactory;
class ArchiveManager { class ArchiveManager {
public: public:
ArchiveManager(); explicit ArchiveManager(Core::System& system);
/** /**
* Opens an archive * Opens an archive
* @param id_code IdCode of the archive to open * @param id_code IdCode of the archive to open
@ -224,6 +229,8 @@ public:
void RegisterSelfNCCH(Loader::AppLoader& app_loader); void RegisterSelfNCCH(Loader::AppLoader& app_loader);
private: private:
Core::System& system;
/** /**
* Registers an Archive type, instances of which can later be opened using its IdCode. * Registers an Archive type, instances of which can later be opened using its IdCode.
* @param factory File system backend interface to the archive * @param factory File system backend interface to the archive

View file

@ -3,6 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h"
#include "core/file_sys/errors.h" #include "core/file_sys/errors.h"
#include "core/file_sys/file_backend.h" #include "core/file_sys/file_backend.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
@ -14,8 +15,9 @@
namespace Service::FS { namespace Service::FS {
File::File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path) File::File(Core::System& system, std::unique_ptr<FileSys::FileBackend>&& backend,
: ServiceFramework("", 1), path(path), backend(std::move(backend)) { const FileSys::Path& path)
: ServiceFramework("", 1), path(path), backend(std::move(backend)), system(system) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0x08010100, &File::OpenSubFile, "OpenSubFile"}, {0x08010100, &File::OpenSubFile, "OpenSubFile"},
{0x080200C2, &File::Read, "Read"}, {0x080200C2, &File::Read, "Read"},
@ -195,7 +197,7 @@ void File::OpenLinkFile(Kernel::HLERequestContext& ctx) {
using Kernel::SharedPtr; using Kernel::SharedPtr;
IPC::RequestParser rp(ctx, 0x080C, 0, 0); IPC::RequestParser rp(ctx, 0x080C, 0, 0);
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
auto sessions = ServerSession::CreateSessionPair(GetName()); auto sessions = system.Kernel().CreateSessionPair(GetName());
auto server = std::get<SharedPtr<ServerSession>>(sessions); auto server = std::get<SharedPtr<ServerSession>>(sessions);
ClientConnected(server); ClientConnected(server);
@ -243,7 +245,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) {
using Kernel::ClientSession; using Kernel::ClientSession;
using Kernel::ServerSession; using Kernel::ServerSession;
using Kernel::SharedPtr; using Kernel::SharedPtr;
auto sessions = ServerSession::CreateSessionPair(GetName()); auto sessions = system.Kernel().CreateSessionPair(GetName());
auto server = std::get<SharedPtr<ServerSession>>(sessions); auto server = std::get<SharedPtr<ServerSession>>(sessions);
ClientConnected(server); ClientConnected(server);
@ -258,7 +260,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) {
} }
Kernel::SharedPtr<Kernel::ClientSession> File::Connect() { Kernel::SharedPtr<Kernel::ClientSession> File::Connect() {
auto sessions = Kernel::ServerSession::CreateSessionPair(GetName()); auto sessions = system.Kernel().CreateSessionPair(GetName());
auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions); auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions);
ClientConnected(server); ClientConnected(server);

View file

@ -8,6 +8,10 @@
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::FS { namespace Service::FS {
struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase { struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase {
@ -21,7 +25,8 @@ struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase {
// Consider splitting ServiceFramework interface. // Consider splitting ServiceFramework interface.
class File final : public ServiceFramework<File, FileSessionSlot> { class File final : public ServiceFramework<File, FileSessionSlot> {
public: public:
File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); File(Core::System& system, std::unique_ptr<FileSys::FileBackend>&& backend,
const FileSys::Path& path);
~File() = default; ~File() = default;
std::string GetName() const { std::string GetName() const {
@ -53,6 +58,8 @@ private:
void GetPriority(Kernel::HLERequestContext& ctx); void GetPriority(Kernel::HLERequestContext& ctx);
void OpenLinkFile(Kernel::HLERequestContext& ctx); void OpenLinkFile(Kernel::HLERequestContext& ctx);
void OpenSubFile(Kernel::HLERequestContext& ctx); void OpenSubFile(Kernel::HLERequestContext& ctx);
Core::System& system;
}; };
} // namespace Service::FS } // namespace Service::FS

View file

@ -286,7 +286,7 @@ void FS_USER::OpenDirectory(Kernel::HLERequestContext& ctx) {
rb.Push(dir_res.Code()); rb.Push(dir_res.Code());
if (dir_res.Succeeded()) { if (dir_res.Succeeded()) {
std::shared_ptr<Directory> directory = *dir_res; std::shared_ptr<Directory> directory = *dir_res;
auto sessions = ServerSession::CreateSessionPair(directory->GetName()); auto sessions = system.Kernel().CreateSessionPair(directory->GetName());
directory->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions)); directory->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions));
rb.PushMoveObjects(std::get<SharedPtr<ClientSession>>(sessions)); rb.PushMoveObjects(std::get<SharedPtr<ClientSession>>(sessions));
} else { } else {
@ -741,7 +741,8 @@ void FS_USER::GetSaveDataSecureValue(Kernel::HLERequestContext& ctx) {
rb.Push<u64>(0); // the secure value rb.Push<u64>(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[] = { static const FunctionInfo functions[] = {
{0x000100C6, nullptr, "Dummy1"}, {0x000100C6, nullptr, "Dummy1"},
{0x040100C4, nullptr, "Control"}, {0x040100C4, nullptr, "Control"},
@ -860,6 +861,6 @@ FS_USER::FS_USER(ArchiveManager& archives) : ServiceFramework("fs:USER", 30), ar
void InstallInterfaces(Core::System& system) { void InstallInterfaces(Core::System& system) {
auto& service_manager = system.ServiceManager(); auto& service_manager = system.ServiceManager();
std::make_shared<FS_USER>(system.ArchiveManager())->InstallAsService(service_manager); std::make_shared<FS_USER>(system)->InstallAsService(service_manager);
} }
} // namespace Service::FS } // namespace Service::FS

View file

@ -17,7 +17,7 @@ class ArchiveManager;
class FS_USER final : public ServiceFramework<FS_USER> { class FS_USER final : public ServiceFramework<FS_USER> {
public: public:
explicit FS_USER(ArchiveManager& archives); explicit FS_USER(Core::System& system);
private: private:
void Initialize(Kernel::HLERequestContext& ctx); void Initialize(Kernel::HLERequestContext& ctx);
@ -534,6 +534,7 @@ private:
u32 priority = -1; ///< For SetPriority and GetPriority service functions u32 priority = -1; ///< For SetPriority and GetPriority service functions
Core::System& system;
ArchiveManager& archives; ArchiveManager& archives;
}; };

View file

@ -22,7 +22,7 @@ static SharedPtr<Object> MakeObject(Kernel::KernelSystem& kernel) {
TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") {
CoreTiming::Init(); CoreTiming::Init();
Kernel::KernelSystem kernel(0); Kernel::KernelSystem kernel(0);
auto session = std::get<SharedPtr<ServerSession>>(ServerSession::CreateSessionPair()); auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair());
HLERequestContext context(std::move(session)); HLERequestContext context(std::move(session));
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));
@ -232,7 +232,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
CoreTiming::Init(); CoreTiming::Init();
Kernel::KernelSystem kernel(0); Kernel::KernelSystem kernel(0);
auto session = std::get<SharedPtr<ServerSession>>(ServerSession::CreateSessionPair()); auto session = std::get<SharedPtr<ServerSession>>(kernel.CreateSessionPair());
HLERequestContext context(std::move(session)); HLERequestContext context(std::move(session));
auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0));