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);
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();
kernel = std::make_unique<Kernel::KernelSystem>(system_mode);

View file

@ -13,7 +13,7 @@
namespace Kernel {
ClientPort::ClientPort(KernelSystem& kernel) {}
ClientPort::ClientPort(KernelSystem& kernel) : kernel(kernel) {}
ClientPort::~ClientPort() = default;
ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
@ -26,7 +26,7 @@ ResultVal<SharedPtr<ClientSession>> 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<SharedPtr<ServerSession>>(sessions));

View file

@ -51,6 +51,7 @@ private:
explicit ClientPort(KernelSystem& kernel);
~ClientPort() override;
KernelSystem& kernel;
SharedPtr<ServerPort> 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

View file

@ -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.

View file

@ -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<Session> parent;
private:
ClientSession();
explicit ClientSession(KernelSystem& kernel);
~ClientSession() override;
};

View file

@ -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<ServerPort>, SharedPtr<ClientPort>> 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<ServerSession>, SharedPtr<ClientSession>> CreateSessionPair(
const std::string& name = "Unknown", SharedPtr<ClientPort> client_port = nullptr);
};
} // namespace Kernel

View file

@ -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<SharedPtr<ServerSession>> ServerSession::Create(std::string name) {
SharedPtr<ServerSession> server_session(new ServerSession);
ResultVal<SharedPtr<ServerSession>> ServerSession::Create(KernelSystem& kernel, std::string name) {
SharedPtr<ServerSession> server_session(new ServerSession(kernel));
server_session->name = std::move(name);
server_session->parent = nullptr;
@ -100,10 +100,10 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
return RESULT_SUCCESS;
}
ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name,
SharedPtr<ClientPort> port) {
auto server_session = ServerSession::Create(name + "_Server").Unwrap();
SharedPtr<ClientSession> client_session(new ClientSession);
std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> KernelSystem::CreateSessionPair(
const std::string& name, SharedPtr<ClientPort> port) {
auto server_session = ServerSession::Create(*this, name + "_Server").Unwrap();
SharedPtr<ClientSession> client_session(new ClientSession(*this));
client_session->name = name + "_Client";
std::shared_ptr<Session> parent(new Session);

View file

@ -48,17 +48,6 @@ public:
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
* instead of the regular IPC machinery. (The regular IPC machinery is currently not
@ -95,16 +84,20 @@ public:
SharedPtr<Thread> 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<SharedPtr<ServerSession>> Create(std::string name = "Unknown");
static ResultVal<SharedPtr<ServerSession>> Create(KernelSystem& kernel,
std::string name = "Unknown");
friend class KernelSystem;
};
} // 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) {
auto sessions = ServerSession::CreateSessionPair();
auto sessions = Core::System::GetInstance().Kernel().CreateSessionPair();
auto& server = std::get<SharedPtr<ServerSession>>(sessions);
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
// Citra will store contents out to sdmc/nand
const FileSys::Path cia_path = {};
auto file =
std::make_shared<Service::FS::File>(std::make_unique<CIAFile>(media_type), cia_path);
auto file = std::make_shared<Service::FS::File>(
am->system, std::make_unique<CIAFile>(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<Service::FS::File>(std::make_unique<CIAFile>(FS::MediaType::NAND),
cia_path);
auto file = std::make_shared<Service::FS::File>(
am->system, std::make_unique<CIAFile>(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");
}

View file

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

View file

@ -87,7 +87,7 @@ ResultVal<std::shared_ptr<File>> ArchiveManager::OpenFileFromArchive(ArchiveHand
if (backend.Failed())
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));
}
@ -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();
}

View file

@ -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

View file

@ -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<FileSys::FileBackend>&& backend, const FileSys::Path& path)
: ServiceFramework("", 1), path(path), backend(std::move(backend)) {
File::File(Core::System& system, std::unique_ptr<FileSys::FileBackend>&& 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<SharedPtr<ServerSession>>(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<SharedPtr<ServerSession>>(sessions);
ClientConnected(server);
@ -258,7 +260,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) {
}
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);
ClientConnected(server);

View file

@ -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<File, FileSessionSlot> {
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;
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

View file

@ -286,7 +286,7 @@ void FS_USER::OpenDirectory(Kernel::HLERequestContext& ctx) {
rb.Push(dir_res.Code());
if (dir_res.Succeeded()) {
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));
rb.PushMoveObjects(std::get<SharedPtr<ClientSession>>(sessions));
} else {
@ -741,7 +741,8 @@ void FS_USER::GetSaveDataSecureValue(Kernel::HLERequestContext& ctx) {
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[] = {
{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<FS_USER>(system.ArchiveManager())->InstallAsService(service_manager);
std::make_shared<FS_USER>(system)->InstallAsService(service_manager);
}
} // namespace Service::FS

View file

@ -17,7 +17,7 @@ class ArchiveManager;
class FS_USER final : public ServiceFramework<FS_USER> {
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;
};

View file

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