service: Migrate global named port map to the KernelCore class

Now that we have a class representing the kernel in some capacity, we
now have a place to put the named port map, so we move it over and get
rid of another piece of global state within the core.
This commit is contained in:
Lioncash 2018-09-02 11:58:58 -04:00
parent 325f3e0693
commit 1242c1ec0a
5 changed files with 51 additions and 19 deletions

View File

@ -13,6 +13,7 @@
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h"
@ -124,6 +125,8 @@ struct KernelCore::Impl {
timer_callback_handle_table.Clear();
timer_callback_event_type = nullptr;
named_ports.clear();
}
void InitializeResourceLimits(KernelCore& kernel) {
@ -217,6 +220,10 @@ struct KernelCore::Impl {
// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future,
// allowing us to simply use a pool index or similar.
Kernel::HandleTable thread_wakeup_callback_handle_table;
/// Map of named ports managed by the kernel, which can be retrieved using
/// the ConnectToPort SVC.
NamedPortTable named_ports;
};
KernelCore::KernelCore() : impl{std::make_unique<Impl>()} {}
@ -257,6 +264,23 @@ void KernelCore::AppendNewProcess(SharedPtr<Process> process) {
impl->process_list.push_back(std::move(process));
}
void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
impl->named_ports.emplace(std::move(name), std::move(port));
}
KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) {
return impl->named_ports.find(name);
}
KernelCore::NamedPortTable::const_iterator KernelCore::FindNamedPort(
const std::string& name) const {
return impl->named_ports.find(name);
}
bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const {
return port != impl->named_ports.cend();
}
u32 KernelCore::CreateNewObjectID() {
return impl->next_object_id++;
}

View File

@ -4,6 +4,8 @@
#pragma once
#include <string>
#include <unordered_map>
#include "core/hle/kernel/object.h"
template <typename T>
@ -15,6 +17,7 @@ struct EventType;
namespace Kernel {
class ClientPort;
class HandleTable;
class Process;
class ResourceLimit;
@ -25,6 +28,9 @@ enum class ResourceLimitCategory : u8;
/// Represents a single instance of the kernel.
class KernelCore {
private:
using NamedPortTable = std::unordered_map<std::string, SharedPtr<ClientPort>>;
public:
KernelCore();
~KernelCore();
@ -59,6 +65,18 @@ public:
/// Adds the given shared pointer to an internal list of active processes.
void AppendNewProcess(SharedPtr<Process> process);
/// Adds a port to the named port table
void AddNamedPort(std::string name, SharedPtr<ClientPort> port);
/// Finds a port within the named port table with the given name.
NamedPortTable::iterator FindNamedPort(const std::string& name);
/// Finds a port within the named port table with the given name.
NamedPortTable::const_iterator FindNamedPort(const std::string& name) const;
/// Determines whether or not the given port is a valid named port.
bool IsValidNamedPort(NamedPortTable::const_iterator port) const;
private:
friend class Object;
friend class Process;

View File

@ -68,19 +68,22 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
/// Connect to an OS service given the port name, returns the handle to the port to out
static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) {
if (!Memory::IsValidVirtualAddress(port_name_address))
if (!Memory::IsValidVirtualAddress(port_name_address)) {
return ERR_NOT_FOUND;
}
static constexpr std::size_t PortNameMaxLength = 11;
// Read 1 char beyond the max allowed port name to detect names that are too long.
std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1);
if (port_name.size() > PortNameMaxLength)
if (port_name.size() > PortNameMaxLength) {
return ERR_PORT_NAME_TOO_LONG;
}
LOG_TRACE(Kernel_SVC, "called port_name={}", port_name);
auto it = Service::g_kernel_named_ports.find(port_name);
if (it == Service::g_kernel_named_ports.end()) {
auto& kernel = Core::System::GetInstance().Kernel();
auto it = kernel.FindNamedPort(port_name);
if (!kernel.IsValidNamedPort(it)) {
LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name);
return ERR_NOT_FOUND;
}
@ -91,7 +94,6 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
CASCADE_RESULT(client_session, client_port->Connect());
// Return the client session
auto& kernel = Core::System::GetInstance().Kernel();
CASCADE_RESULT(*out_handle, kernel.HandleTable().Create(client_session));
return RESULT_SUCCESS;
}

View File

@ -12,6 +12,7 @@
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/server_port.h"
#include "core/hle/kernel/thread.h"
@ -114,7 +115,7 @@ void ServiceFrameworkBase::InstallAsNamedPort() {
std::tie(server_port, client_port) =
ServerPort::CreatePortPair(kernel, max_sessions, service_name);
server_port->SetHleHandler(shared_from_this());
AddNamedPort(service_name, std::move(client_port));
kernel.AddNamedPort(service_name, std::move(client_port));
}
Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() {
@ -197,11 +198,6 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
////////////////////////////////////////////////////////////////////////////////////////////////////
// Module interface
// TODO(yuriks): Move to kernel
void AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
g_kernel_named_ports.emplace(std::move(name), std::move(port));
}
/// Initialize ServiceManager
void Init(std::shared_ptr<SM::ServiceManager>& sm, const FileSys::VirtualFilesystem& rfs) {
// NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
@ -264,7 +260,6 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, const FileSys::VirtualFilesys
/// Shutdown ServiceManager
void Shutdown() {
g_kernel_named_ports.clear();
LOG_DEBUG(Service, "shutdown OK");
}
} // namespace Service

View File

@ -6,7 +6,6 @@
#include <cstddef>
#include <string>
#include <unordered_map>
#include <boost/container/flat_map.hpp>
#include "common/common_types.h"
#include "core/hle/kernel/hle_ipc.h"
@ -187,10 +186,4 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm,
/// Shutdown ServiceManager
void Shutdown();
/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort SVC.
extern std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ClientPort>> g_kernel_named_ports;
/// Adds a port to the named port table
void AddNamedPort(std::string name, Kernel::SharedPtr<Kernel::ClientPort> port);
} // namespace Service