Revert "WIP (#5)"

This reverts commit 8cecbb5231.
This commit is contained in:
Dragios 2016-04-16 01:32:38 +08:00
parent 373a925693
commit 8c0256d95c
9 changed files with 38 additions and 166 deletions

View File

@ -35,8 +35,8 @@ enum KernelHandle : Handle {
enum class HandleType : u32 { enum class HandleType : u32 {
Unknown = 0, Unknown = 0,
ServerPort = 1, Port = 1,
ClientSession = 2, Session = 2,
Event = 3, Event = 3,
Mutex = 4, Mutex = 4,
SharedMemory = 5, SharedMemory = 5,
@ -48,7 +48,6 @@ enum class HandleType : u32 {
Timer = 11, Timer = 11,
ResourceLimit = 12, ResourceLimit = 12,
CodeSet = 13, CodeSet = 13,
ServerSession = 14,
}; };
enum { enum {
@ -72,7 +71,7 @@ public:
*/ */
bool IsWaitable() const { bool IsWaitable() const {
switch (GetHandleType()) { switch (GetHandleType()) {
case HandleType::ClientSession: case HandleType::Session:
case HandleType::Event: case HandleType::Event:
case HandleType::Mutex: case HandleType::Mutex:
case HandleType::Thread: case HandleType::Thread:
@ -81,14 +80,13 @@ public:
return true; return true;
case HandleType::Unknown: case HandleType::Unknown:
case HandleType::ServerPort: case HandleType::Port:
case HandleType::SharedMemory: case HandleType::SharedMemory:
case HandleType::Redirection: case HandleType::Redirection:
case HandleType::Process: case HandleType::Process:
case HandleType::AddressArbiter: case HandleType::AddressArbiter:
case HandleType::ResourceLimit: case HandleType::ResourceLimit:
case HandleType::CodeSet: case HandleType::CodeSet:
case HandleType::ServerSession:
return false; return false;
} }
} }

View File

@ -1,55 +1,13 @@
// Copyright 2016 Citra Emulator Project // Copyright 2015 Citra Emulator Project
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "core/hle/kernel/session.h" #include "core/hle/kernel/session.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/thread.h" #include "core/hle/kernel/thread.h"
namespace Kernel { namespace Kernel {
SharedPtr<ServerPort> ServerPort::Create(const std::string& name, u32 max_sessions) { Session::Session() {}
SharedPtr<ServerPort> server_port(new ServerPort); Session::~Session() {}
server_port->name = name;
server_port->owner_process = g_current_process;
server_port->max_sessions = max_sessions;
return server_port;
}
SharedPtr<ClientSession> ServerPort::CreateSession() {
SharedPtr<ClientSession> client_session(new ClientSession);
if (IsHLE()) {
client_session->hle_port = this;
} else {
SharedPtr<ServerSession> server_session(new ServerSession);
client_session->server_session = server_session;
pending_sessions.push_back(server_session);
// Set the register to the value of the triggered index from svcReplyAndReceive
WakeupAllWaitingThreads();
}
// TODO(Subv): Schedule to the thread waiting on svcReplyAndReceive
return client_session;
}
ClientSession::ClientSession() {}
ClientSession::~ClientSession() {}
ResultVal<bool> ClientSession::SyncRequest() {
if (hle_port) {
hle_port->SyncRequest();
} else {
server_session->data_ready = true;
server_session->waiting_thread = Kernel::GetCurrentThread();
// TODO(Subv): Sleep the current thread until the response is ready
// TODO(Subv): Immediately schedule the handler thread
}
return MakeResult<bool>(true);
}
ResultVal<bool> ServerPort::SyncRequest() {
return MakeResult<bool>(true);
}
} }

View File

@ -10,7 +10,6 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/thread.h" #include "core/hle/kernel/thread.h"
#include "core/hle/result.h" #include "core/hle/result.h"
#include "core/memory.h" #include "core/memory.h"
@ -65,28 +64,6 @@ inline static u32* GetCommandBuffer(const int offset = 0) {
return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + offset); return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + offset);
} }
class ServerSession : public WaitObject {
public:
std::string GetTypeName() const override { return "ServerSession"; }
static const HandleType HANDLE_TYPE = HandleType::ServerSession;
HandleType GetHandleType() const override { return HANDLE_TYPE; }
bool ShouldWait() override {
return !data_ready;
}
void Acquire() override {
data_ready = false;
}
bool data_ready;
SharedPtr<Thread> handler_thread;
SharedPtr<Thread> waiting_thread;
};
class ServerPort;
/** /**
* Kernel object representing the client endpoint of an IPC session. Sessions are the basic CTR-OS * Kernel object representing the client endpoint of an IPC session. Sessions are the basic CTR-OS
* primitive for communication between different processes, and are used to implement service calls * primitive for communication between different processes, and are used to implement service calls
@ -109,21 +86,21 @@ class ServerPort;
* CTR-OS so that IPC calls can be optionally handled by the real implementations of processes, as * CTR-OS so that IPC calls can be optionally handled by the real implementations of processes, as
* opposed to HLE simulations. * opposed to HLE simulations.
*/ */
class ClientSession : public WaitObject { class Session : public WaitObject {
public: public:
ClientSession(); Session();
~ClientSession() override; ~Session() override;
std::string GetTypeName() const override { return "ClientSession"; } std::string GetTypeName() const override { return "Session"; }
static const HandleType HANDLE_TYPE = HandleType::ClientSession; static const HandleType HANDLE_TYPE = HandleType::Session;
HandleType GetHandleType() const override { return HANDLE_TYPE; } HandleType GetHandleType() const override { return HANDLE_TYPE; }
/** /**
* Handles a synchronous call to this session using HLE emulation. Emulated <-> emulated calls * Handles a synchronous call to this session using HLE emulation. Emulated <-> emulated calls
* aren't supported yet. * aren't supported yet.
*/ */
virtual ResultVal<bool> SyncRequest(); virtual ResultVal<bool> SyncRequest() = 0;
// TODO(bunnei): These functions exist to satisfy a hardware test with a Session object // TODO(bunnei): These functions exist to satisfy a hardware test with a Session object
// passed into WaitSynchronization. Figure out the meaning of them. // passed into WaitSynchronization. Figure out the meaning of them.
@ -135,50 +112,6 @@ public:
void Acquire() override { void Acquire() override {
ASSERT_MSG(!ShouldWait(), "object unavailable!"); ASSERT_MSG(!ShouldWait(), "object unavailable!");
} }
SharedPtr<ServerSession> server_session;
SharedPtr<ServerPort> hle_port;
};
class ServerPort : public WaitObject {
public:
std::string GetTypeName() const override { return "ServerPort"; }
static const HandleType HANDLE_TYPE = HandleType::ServerPort;
HandleType GetHandleType() const override { return HANDLE_TYPE; }
/**
* Gets the string name used by CTROS for a service
* @return Port name of service
*/
virtual std::string GetPortName() const {
return name;
}
virtual ResultVal<bool> SyncRequest();
std::string GetName() const override { return GetPortName(); }
static SharedPtr<ServerPort> Create(const std::string& name, u32 max_sessions);
SharedPtr<ClientSession> CreateSession();
virtual bool IsHLE() const { return false; }
bool ShouldWait() override {
return pending_sessions.empty();
}
void Acquire() override {
}
private:
std::string name;
SharedPtr<Process> owner_process;
u32 max_sessions;
std::vector<SharedPtr<ServerSession>> pending_sessions;
}; };
} }

View File

@ -46,7 +46,7 @@ enum class MediaType : u32 {
typedef u64 ArchiveHandle; typedef u64 ArchiveHandle;
class File : public Kernel::ClientSession { class File : public Kernel::Session {
public: public:
File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path);
~File(); ~File();
@ -59,7 +59,7 @@ public:
std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface
}; };
class Directory : public Kernel::ClientSession { class Directory : public Kernel::Session {
public: public:
Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path); Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path);
~Directory(); ~Directory();

View File

@ -18,7 +18,7 @@
// Namespace FS_User // Namespace FS_User
using Kernel::SharedPtr; using Kernel::SharedPtr;
using Kernel::ClientSession; using Kernel::Session;
namespace Service { namespace Service {
namespace FS { namespace FS {

View File

@ -5,7 +5,6 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/string_util.h" #include "common/string_util.h"
#include "core/hle/kernel/session.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
#include "core/hle/service/ac_u.h" #include "core/hle/service/ac_u.h"
#include "core/hle/service/act_u.h" #include "core/hle/service/act_u.h"
@ -43,8 +42,8 @@
namespace Service { namespace Service {
std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ServerPort>> g_kernel_named_ports; std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports;
std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ServerPort>> g_srv_services; std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services;
/** /**
* Creates a function string for logging, complete with the name (or header code, depending * Creates a function string for logging, complete with the name (or header code, depending
@ -91,11 +90,11 @@ void Interface::Register(const FunctionInfo* functions, size_t n) {
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Module interface // Module interface
static void AddNamedPort(Kernel::ServerPort* interface_) { static void AddNamedPort(Interface* interface_) {
g_kernel_named_ports.emplace(interface_->GetPortName(), interface_); g_kernel_named_ports.emplace(interface_->GetPortName(), interface_);
} }
void AddService(Kernel::ServerPort* interface_) { void AddService(Interface* interface_) {
g_srv_services.emplace(interface_->GetPortName(), interface_); g_srv_services.emplace(interface_->GetPortName(), interface_);
} }

View File

@ -23,11 +23,13 @@ namespace Service {
static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters) static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters)
/// Interface to a CTROS service /// Interface to a CTROS service
class Interface : public Kernel::ServerPort { class Interface : public Kernel::Session {
// TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be // TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be
// just something that encapsulates a session and acts as a helper to implement service // just something that encapsulates a session and acts as a helper to implement service
// processes. // processes.
public: public:
std::string GetName() const override { return GetPortName(); }
typedef void (*Function)(Interface*); typedef void (*Function)(Interface*);
struct FunctionInfo { struct FunctionInfo {
@ -36,9 +38,15 @@ public:
const char* name; const char* name;
}; };
ResultVal<bool> SyncRequest() override; /**
* Gets the string name used by CTROS for a service
* @return Port name of service
*/
virtual std::string GetPortName() const {
return "[UNKNOWN SERVICE PORT]";
}
bool IsHLE() const override { return true; } ResultVal<bool> SyncRequest() override;
protected: protected:
@ -64,11 +72,11 @@ void Init();
void Shutdown(); void Shutdown();
/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort SVC. /// 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::ServerPort>> g_kernel_named_ports; extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports;
/// Map of services registered with the "srv:" service, retrieved using GetServiceHandle. /// Map of services registered with the "srv:" service, retrieved using GetServiceHandle.
extern std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ServerPort>> g_srv_services; extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services;
/// Adds a service to the services table /// Adds a service to the services table
void AddService(Kernel::ServerPort* interface_); void AddService(Interface* interface_);
} // namespace } // namespace

View File

@ -40,8 +40,7 @@ static void GetServiceHandle(Service::Interface* self) {
auto it = Service::g_srv_services.find(port_name); auto it = Service::g_srv_services.find(port_name);
if (it != Service::g_srv_services.end()) { if (it != Service::g_srv_services.end()) {
auto client_session = it->second->CreateSession(); cmd_buff[3] = Kernel::g_handle_table.Create(it->second).MoveFrom();
cmd_buff[3] = Kernel::g_handle_table.Create(client_session).MoveFrom();
LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]); LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]);
} else { } else {
LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str()); LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str());
@ -50,31 +49,10 @@ static void GetServiceHandle(Service::Interface* self) {
cmd_buff[1] = res.raw; cmd_buff[1] = res.raw;
} }
static void RegisterService(Service::Interface* self) {
ResultCode res = RESULT_SUCCESS;
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 max_sessions = cmd_buff[4];
std::string port_name = std::string((const char*)&cmd_buff[1], 0, std::min<u32>(cmd_buff[3], Service::kMaxPortSize));
auto it = Service::g_srv_services.find(port_name);
if (it != Service::g_srv_services.end()) {
LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s already exists", port_name.c_str());
res = UnimplementedFunction(ErrorModule::SRV);
} else {
LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]);
auto server_port = Kernel::ServerPort::Create(port_name, max_sessions);
Service::g_srv_services.emplace(port_name, server_port);
cmd_buff[3] = Kernel::g_handle_table.Create(server_port).MoveFrom();
}
cmd_buff[1] = res.raw;
}
const Interface::FunctionInfo FunctionTable[] = { const Interface::FunctionInfo FunctionTable[] = {
{0x00010002, Initialize, "Initialize"}, {0x00010002, Initialize, "Initialize"},
{0x00020000, GetProcSemaphore, "GetProcSemaphore"}, {0x00020000, GetProcSemaphore, "GetProcSemaphore"},
{0x00030100, RegisterService, "RegisterService"}, {0x00030100, nullptr, "RegisterService"},
{0x000400C0, nullptr, "UnregisterService"}, {0x000400C0, nullptr, "UnregisterService"},
{0x00050100, GetServiceHandle, "GetServiceHandle"}, {0x00050100, GetServiceHandle, "GetServiceHandle"},
{0x000600C2, nullptr, "RegisterHandle"}, {0x000600C2, nullptr, "RegisterHandle"},

View File

@ -215,15 +215,13 @@ static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) {
return ERR_NOT_FOUND; return ERR_NOT_FOUND;
} }
// TODO(Subv): This should return a ClientPort, not a ClientSession CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(it->second));
auto session = it->second->CreateSession();
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(session));
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
/// Synchronize to an OS service /// Synchronize to an OS service
static ResultCode SendSyncRequest(Handle handle) { static ResultCode SendSyncRequest(Handle handle) {
SharedPtr<Kernel::ClientSession> session = Kernel::g_handle_table.Get<Kernel::ClientSession>(handle); SharedPtr<Kernel::Session> session = Kernel::g_handle_table.Get<Kernel::Session>(handle);
if (session == nullptr) { if (session == nullptr) {
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
} }