diff options
| author | 2016-06-14 18:03:30 -0500 | |
|---|---|---|
| committer | 2016-11-30 23:02:05 -0500 | |
| commit | 073653e858abf377fd1ebbdb071809c8830ce99d (patch) | |
| tree | a29e1c1e50d53162ed89cd90e8c069525150392f /src/core/hle/service | |
| parent | Merge pull request #2228 from freiro/winver_fix (diff) | |
| download | yuzu-073653e858abf377fd1ebbdb071809c8830ce99d.tar.gz yuzu-073653e858abf377fd1ebbdb071809c8830ce99d.tar.xz yuzu-073653e858abf377fd1ebbdb071809c8830ce99d.zip | |
Kernel/IPC: Use Ports and Sessions as the fundamental building block of Inter Process Communication.
All handles obtained via srv::GetServiceHandle or svcConnectToPort are references to ClientSessions.
Service modules will wait on the counterpart of those ClientSessions (Called ServerSessions) using svcReplyAndReceive or svcWaitSynchronization[1|N], and will be awoken when a SyncRequest is performed.
HLE Interfaces are now ClientPorts which override the HandleSyncRequest virtual member function to perform command handling immediately.
Diffstat (limited to 'src/core/hle/service')
| -rw-r--r-- | src/core/hle/service/fs/archive.cpp | 12 | ||||
| -rw-r--r-- | src/core/hle/service/fs/archive.h | 12 | ||||
| -rw-r--r-- | src/core/hle/service/fs/fs_user.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 16 | ||||
| -rw-r--r-- | src/core/hle/service/service.h | 21 | ||||
| -rw-r--r-- | src/core/hle/service/soc_u.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/srv.cpp | 17 |
7 files changed, 62 insertions, 27 deletions
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 4c29784e8..da009df91 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp | |||
| @@ -92,7 +92,7 @@ File::File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& | |||
| 92 | 92 | ||
| 93 | File::~File() {} | 93 | File::~File() {} |
| 94 | 94 | ||
| 95 | ResultVal<bool> File::SyncRequest() { | 95 | ResultCode File::HandleSyncRequest() { |
| 96 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 96 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 97 | FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); | 97 | FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); |
| 98 | switch (cmd) { | 98 | switch (cmd) { |
| @@ -193,10 +193,10 @@ ResultVal<bool> File::SyncRequest() { | |||
| 193 | LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); | 193 | LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); |
| 194 | ResultCode error = UnimplementedFunction(ErrorModule::FS); | 194 | ResultCode error = UnimplementedFunction(ErrorModule::FS); |
| 195 | cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. | 195 | cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. |
| 196 | return error; | 196 | return ServerSession::HandleSyncRequest(); |
| 197 | } | 197 | } |
| 198 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 198 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 199 | return MakeResult<bool>(false); | 199 | return ServerSession::HandleSyncRequest(); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, | 202 | Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, |
| @@ -205,7 +205,7 @@ Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, | |||
| 205 | 205 | ||
| 206 | Directory::~Directory() {} | 206 | Directory::~Directory() {} |
| 207 | 207 | ||
| 208 | ResultVal<bool> Directory::SyncRequest() { | 208 | ResultCode Directory::HandleSyncRequest() { |
| 209 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 209 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 210 | DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]); | 210 | DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]); |
| 211 | switch (cmd) { | 211 | switch (cmd) { |
| @@ -236,10 +236,10 @@ ResultVal<bool> Directory::SyncRequest() { | |||
| 236 | LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); | 236 | LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); |
| 237 | ResultCode error = UnimplementedFunction(ErrorModule::FS); | 237 | ResultCode error = UnimplementedFunction(ErrorModule::FS); |
| 238 | cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. | 238 | cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. |
| 239 | return MakeResult<bool>(false); | 239 | return ServerSession::HandleSyncRequest(); |
| 240 | } | 240 | } |
| 241 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 241 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 242 | return MakeResult<bool>(false); | 242 | return ServerSession::HandleSyncRequest(); |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 245 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 21ed9717b..22e659c40 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #include <string> | 8 | #include <string> |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/file_sys/archive_backend.h" | 10 | #include "core/file_sys/archive_backend.h" |
| 11 | #include "core/hle/kernel/session.h" | 11 | #include "core/hle/kernel/server_session.h" |
| 12 | #include "core/hle/result.h" | 12 | #include "core/hle/result.h" |
| 13 | 13 | ||
| 14 | namespace FileSys { | 14 | namespace FileSys { |
| @@ -41,7 +41,7 @@ enum class MediaType : u32 { NAND = 0, SDMC = 1 }; | |||
| 41 | 41 | ||
| 42 | typedef u64 ArchiveHandle; | 42 | typedef u64 ArchiveHandle; |
| 43 | 43 | ||
| 44 | class File : public Kernel::Session { | 44 | class File : public Kernel::ServerSession { |
| 45 | public: | 45 | public: |
| 46 | File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); | 46 | File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); |
| 47 | ~File(); | 47 | ~File(); |
| @@ -49,14 +49,15 @@ public: | |||
| 49 | std::string GetName() const override { | 49 | std::string GetName() const override { |
| 50 | return "Path: " + path.DebugStr(); | 50 | return "Path: " + path.DebugStr(); |
| 51 | } | 51 | } |
| 52 | ResultVal<bool> SyncRequest() override; | 52 | |
| 53 | ResultCode HandleSyncRequest() override; | ||
| 53 | 54 | ||
| 54 | FileSys::Path path; ///< Path of the file | 55 | FileSys::Path path; ///< Path of the file |
| 55 | u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means | 56 | u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means |
| 56 | std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface | 57 | std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface |
| 57 | }; | 58 | }; |
| 58 | 59 | ||
| 59 | class Directory : public Kernel::Session { | 60 | class Directory : public Kernel::ServerSession { |
| 60 | public: | 61 | public: |
| 61 | Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path); | 62 | Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path); |
| 62 | ~Directory(); | 63 | ~Directory(); |
| @@ -64,7 +65,8 @@ public: | |||
| 64 | std::string GetName() const override { | 65 | std::string GetName() const override { |
| 65 | return "Directory: " + path.DebugStr(); | 66 | return "Directory: " + path.DebugStr(); |
| 66 | } | 67 | } |
| 67 | ResultVal<bool> SyncRequest() override; | 68 | |
| 69 | ResultCode HandleSyncRequest() override; | ||
| 68 | 70 | ||
| 69 | FileSys::Path path; ///< Path of the directory | 71 | FileSys::Path path; ///< Path of the directory |
| 70 | std::unique_ptr<FileSys::DirectoryBackend> backend; ///< File backend interface | 72 | std::unique_ptr<FileSys::DirectoryBackend> backend; ///< File backend interface |
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index 9ec17b395..bb78091f9 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 9 | #include "common/scope_exit.h" | 9 | #include "common/scope_exit.h" |
| 10 | #include "common/string_util.h" | 10 | #include "common/string_util.h" |
| 11 | #include "core/hle/kernel/client_session.h" | ||
| 11 | #include "core/hle/result.h" | 12 | #include "core/hle/result.h" |
| 12 | #include "core/hle/service/fs/archive.h" | 13 | #include "core/hle/service/fs/archive.h" |
| 13 | #include "core/hle/service/fs/fs_user.h" | 14 | #include "core/hle/service/fs/fs_user.h" |
| @@ -17,7 +18,7 @@ | |||
| 17 | // Namespace FS_User | 18 | // Namespace FS_User |
| 18 | 19 | ||
| 19 | using Kernel::SharedPtr; | 20 | using Kernel::SharedPtr; |
| 20 | using Kernel::Session; | 21 | using Kernel::ServerSession; |
| 21 | 22 | ||
| 22 | namespace Service { | 23 | namespace Service { |
| 23 | namespace FS { | 24 | namespace FS { |
| @@ -70,7 +71,7 @@ static void OpenFile(Service::Interface* self) { | |||
| 70 | ResultVal<SharedPtr<File>> file_res = OpenFileFromArchive(archive_handle, file_path, mode); | 71 | ResultVal<SharedPtr<File>> file_res = OpenFileFromArchive(archive_handle, file_path, mode); |
| 71 | cmd_buff[1] = file_res.Code().raw; | 72 | cmd_buff[1] = file_res.Code().raw; |
| 72 | if (file_res.Succeeded()) { | 73 | if (file_res.Succeeded()) { |
| 73 | cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom(); | 74 | cmd_buff[3] = Kernel::g_handle_table.Create((*file_res)->CreateClientSession()).MoveFrom(); |
| 74 | } else { | 75 | } else { |
| 75 | cmd_buff[3] = 0; | 76 | cmd_buff[3] = 0; |
| 76 | LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); | 77 | LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); |
| @@ -130,7 +131,7 @@ static void OpenFileDirectly(Service::Interface* self) { | |||
| 130 | ResultVal<SharedPtr<File>> file_res = OpenFileFromArchive(*archive_handle, file_path, mode); | 131 | ResultVal<SharedPtr<File>> file_res = OpenFileFromArchive(*archive_handle, file_path, mode); |
| 131 | cmd_buff[1] = file_res.Code().raw; | 132 | cmd_buff[1] = file_res.Code().raw; |
| 132 | if (file_res.Succeeded()) { | 133 | if (file_res.Succeeded()) { |
| 133 | cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom(); | 134 | cmd_buff[3] = Kernel::g_handle_table.Create((*file_res)->CreateClientSession()).MoveFrom(); |
| 134 | } else { | 135 | } else { |
| 135 | cmd_buff[3] = 0; | 136 | cmd_buff[3] = 0; |
| 136 | LOG_ERROR(Service_FS, "failed to get a handle for file %s mode=%u attributes=%u", | 137 | LOG_ERROR(Service_FS, "failed to get a handle for file %s mode=%u attributes=%u", |
| @@ -391,7 +392,7 @@ static void OpenDirectory(Service::Interface* self) { | |||
| 391 | ResultVal<SharedPtr<Directory>> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path); | 392 | ResultVal<SharedPtr<Directory>> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path); |
| 392 | cmd_buff[1] = dir_res.Code().raw; | 393 | cmd_buff[1] = dir_res.Code().raw; |
| 393 | if (dir_res.Succeeded()) { | 394 | if (dir_res.Succeeded()) { |
| 394 | cmd_buff[3] = Kernel::g_handle_table.Create(*dir_res).MoveFrom(); | 395 | cmd_buff[3] = Kernel::g_handle_table.Create((*dir_res)->CreateClientSession()).MoveFrom(); |
| 395 | } else { | 396 | } else { |
| 396 | LOG_ERROR(Service_FS, "failed to get a handle for directory type=%d size=%d data=%s", | 397 | LOG_ERROR(Service_FS, "failed to get a handle for directory type=%d size=%d data=%s", |
| 397 | dirname_type, dirname_size, dir_path.DebugStr().c_str()); | 398 | dirname_type, dirname_size, dir_path.DebugStr().c_str()); |
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index ca7eeac8a..f51a042ff 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -41,8 +41,8 @@ | |||
| 41 | 41 | ||
| 42 | namespace Service { | 42 | namespace Service { |
| 43 | 43 | ||
| 44 | std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports; | 44 | std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ClientPort>> g_kernel_named_ports; |
| 45 | std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services; | 45 | std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ClientPort>> g_srv_services; |
| 46 | 46 | ||
| 47 | /** | 47 | /** |
| 48 | * Creates a function string for logging, complete with the name (or header code, depending | 48 | * Creates a function string for logging, complete with the name (or header code, depending |
| @@ -61,7 +61,7 @@ static std::string MakeFunctionString(const char* name, const char* port_name, | |||
| 61 | return function_string; | 61 | return function_string; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | ResultVal<bool> Interface::SyncRequest() { | 64 | ResultCode Interface::HandleSyncRequest() { |
| 65 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 65 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 66 | auto itr = m_functions.find(cmd_buff[0]); | 66 | auto itr = m_functions.find(cmd_buff[0]); |
| 67 | 67 | ||
| @@ -75,14 +75,14 @@ ResultVal<bool> Interface::SyncRequest() { | |||
| 75 | 75 | ||
| 76 | // TODO(bunnei): Hack - ignore error | 76 | // TODO(bunnei): Hack - ignore error |
| 77 | cmd_buff[1] = 0; | 77 | cmd_buff[1] = 0; |
| 78 | return MakeResult<bool>(false); | 78 | return RESULT_SUCCESS; |
| 79 | } | 79 | } |
| 80 | LOG_TRACE(Service, "%s", | 80 | LOG_TRACE(Service, "%s", |
| 81 | MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); | 81 | MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); |
| 82 | 82 | ||
| 83 | itr->second.func(this); | 83 | itr->second.func(this); |
| 84 | 84 | ||
| 85 | return MakeResult<bool>(false); // TODO: Implement return from actual function | 85 | return RESULT_SUCCESS; // TODO: Implement return from actual function, it should fail if the parameter translation fails |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | void Interface::Register(const FunctionInfo* functions, size_t n) { | 88 | void Interface::Register(const FunctionInfo* functions, size_t n) { |
| @@ -97,10 +97,16 @@ void Interface::Register(const FunctionInfo* functions, size_t n) { | |||
| 97 | // Module interface | 97 | // Module interface |
| 98 | 98 | ||
| 99 | static void AddNamedPort(Interface* interface_) { | 99 | static void AddNamedPort(Interface* interface_) { |
| 100 | interface_->name = interface_->GetPortName(); | ||
| 101 | interface_->active_sessions = 0; | ||
| 102 | interface_->max_sessions = interface_->GetMaxSessions(); | ||
| 100 | g_kernel_named_ports.emplace(interface_->GetPortName(), interface_); | 103 | g_kernel_named_ports.emplace(interface_->GetPortName(), interface_); |
| 101 | } | 104 | } |
| 102 | 105 | ||
| 103 | void AddService(Interface* interface_) { | 106 | void AddService(Interface* interface_) { |
| 107 | interface_->name = interface_->GetPortName(); | ||
| 108 | interface_->active_sessions = 0; | ||
| 109 | interface_->max_sessions = interface_->GetMaxSessions(); | ||
| 104 | g_srv_services.emplace(interface_->GetPortName(), interface_); | 110 | g_srv_services.emplace(interface_->GetPortName(), interface_); |
| 105 | } | 111 | } |
| 106 | 112 | ||
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 29daacfc4..fd15ad03f 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h | |||
| @@ -9,7 +9,8 @@ | |||
| 9 | #include <unordered_map> | 9 | #include <unordered_map> |
| 10 | #include <boost/container/flat_map.hpp> | 10 | #include <boost/container/flat_map.hpp> |
| 11 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "core/hle/kernel/session.h" | 12 | #include "core/hle/kernel/client_port.h" |
| 13 | #include "core/hle/kernel/server_session.h" | ||
| 13 | #include "core/hle/result.h" | 14 | #include "core/hle/result.h" |
| 14 | 15 | ||
| 15 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 16 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -18,9 +19,10 @@ | |||
| 18 | namespace Service { | 19 | namespace Service { |
| 19 | 20 | ||
| 20 | static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters) | 21 | static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters) |
| 22 | static const u32 DefaultMaxSessions = 10; ///< Arbitrary default number of maximum connections to an HLE port | ||
| 21 | 23 | ||
| 22 | /// Interface to a CTROS service | 24 | /// Interface to a CTROS service |
| 23 | class Interface : public Kernel::Session { | 25 | class Interface : public Kernel::ClientPort { |
| 24 | // TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be | 26 | // TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be |
| 25 | // just something that encapsulates a session and acts as a helper to implement service | 27 | // just something that encapsulates a session and acts as a helper to implement service |
| 26 | // processes. | 28 | // processes. |
| @@ -33,6 +35,15 @@ public: | |||
| 33 | version.raw = raw_version; | 35 | version.raw = raw_version; |
| 34 | } | 36 | } |
| 35 | 37 | ||
| 38 | /** | ||
| 39 | * Gets the maximum allowed number of sessions that can be connected to this port at the same time. | ||
| 40 | * It should be overwritten by each service implementation for more fine-grained control. | ||
| 41 | * @returns The maximum number of connections allowed. | ||
| 42 | */ | ||
| 43 | virtual u32 GetMaxSessions() { return DefaultMaxSessions; } | ||
| 44 | |||
| 45 | void AddWaitingSession(Kernel::SharedPtr<Kernel::ServerSession> server_session) override { } | ||
| 46 | |||
| 36 | typedef void (*Function)(Interface*); | 47 | typedef void (*Function)(Interface*); |
| 37 | 48 | ||
| 38 | struct FunctionInfo { | 49 | struct FunctionInfo { |
| @@ -49,7 +60,7 @@ public: | |||
| 49 | return "[UNKNOWN SERVICE PORT]"; | 60 | return "[UNKNOWN SERVICE PORT]"; |
| 50 | } | 61 | } |
| 51 | 62 | ||
| 52 | ResultVal<bool> SyncRequest() override; | 63 | ResultCode HandleSyncRequest() override; |
| 53 | 64 | ||
| 54 | protected: | 65 | protected: |
| 55 | /** | 66 | /** |
| @@ -81,9 +92,9 @@ void Init(); | |||
| 81 | void Shutdown(); | 92 | void Shutdown(); |
| 82 | 93 | ||
| 83 | /// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort SVC. | 94 | /// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort SVC. |
| 84 | extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports; | 95 | extern std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ClientPort>> g_kernel_named_ports; |
| 85 | /// Map of services registered with the "srv:" service, retrieved using GetServiceHandle. | 96 | /// Map of services registered with the "srv:" service, retrieved using GetServiceHandle. |
| 86 | extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services; | 97 | extern std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ClientPort>> g_srv_services; |
| 87 | 98 | ||
| 88 | /// Adds a service to the services table | 99 | /// Adds a service to the services table |
| 89 | void AddService(Interface* interface_); | 100 | void AddService(Interface* interface_); |
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 46b75db25..2e8b2fc00 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "common/logging/log.h" | 12 | #include "common/logging/log.h" |
| 13 | #include "common/scope_exit.h" | 13 | #include "common/scope_exit.h" |
| 14 | #include "core/hle/kernel/session.h" | 14 | #include "core/hle/kernel/server_session.h" |
| 15 | #include "core/hle/result.h" | 15 | #include "core/hle/result.h" |
| 16 | #include "core/hle/service/soc_u.h" | 16 | #include "core/hle/service/soc_u.h" |
| 17 | #include "core/memory.h" | 17 | #include "core/memory.h" |
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index b25be413a..eb2e06041 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp | |||
| @@ -2,8 +2,12 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <tuple> | ||
| 6 | |||
| 5 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 6 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 9 | #include "core/hle/service/srv.h" | ||
| 10 | #include "core/hle/kernel/client_session.h" | ||
| 7 | #include "core/hle/kernel/event.h" | 11 | #include "core/hle/kernel/event.h" |
| 8 | #include "core/hle/service/srv.h" | 12 | #include "core/hle/service/srv.h" |
| 9 | 13 | ||
| @@ -81,7 +85,18 @@ static void GetServiceHandle(Service::Interface* self) { | |||
| 81 | auto it = Service::g_srv_services.find(port_name); | 85 | auto it = Service::g_srv_services.find(port_name); |
| 82 | 86 | ||
| 83 | if (it != Service::g_srv_services.end()) { | 87 | if (it != Service::g_srv_services.end()) { |
| 84 | cmd_buff[3] = Kernel::g_handle_table.Create(it->second).MoveFrom(); | 88 | auto client_port = it->second; |
| 89 | |||
| 90 | // Create a new session pair | ||
| 91 | auto sessions = Kernel::ServerSession::CreateSessionPair(client_port, port_name); | ||
| 92 | auto client_session = std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions); | ||
| 93 | auto server_session = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions); | ||
| 94 | |||
| 95 | // Add the server session to the port's queue | ||
| 96 | client_port->AddWaitingSession(server_session); | ||
| 97 | |||
| 98 | // Return the client session | ||
| 99 | cmd_buff[3] = Kernel::g_handle_table.Create(client_session).MoveFrom(); | ||
| 85 | LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]); | 100 | LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]); |
| 86 | } else { | 101 | } else { |
| 87 | LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str()); | 102 | LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str()); |