mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-30 23:49:01 -05:00 
			
		
		
		
	Use std::move where appropriate.
This commit is contained in:
		| @@ -179,6 +179,7 @@ set(HEADERS | ||||
|             hle/config_mem.h | ||||
|             hle/function_wrappers.h | ||||
|             hle/hle.h | ||||
|             hle/ipc.h | ||||
|             hle/applets/applet.h | ||||
|             hle/applets/erreula.h | ||||
|             hle/applets/mii_selector.h | ||||
|   | ||||
							
								
								
									
										162
									
								
								src/core/hle/ipc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								src/core/hle/ipc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | ||||
| // Copyright 2016 Citra Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/memory.h" | ||||
|  | ||||
| namespace Kernel { | ||||
| class ServerSession; | ||||
|  | ||||
| // TODO(Subv): Move these declarations out of here | ||||
| static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header | ||||
|  | ||||
| /** | ||||
|  * Returns a pointer to the command buffer in the current thread's TLS | ||||
|  * TODO(Subv): This is not entirely correct, the command buffer should be copied from | ||||
|  * the thread's TLS to an intermediate buffer in kernel memory, and then copied again to | ||||
|  * the service handler process' memory. | ||||
|  * @param offset Optional offset into command buffer | ||||
|  * @return Pointer to command buffer | ||||
|  */ | ||||
| inline u32* GetCommandBuffer(const int offset = 0) { | ||||
|     return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + | ||||
|                                     offset); | ||||
| } | ||||
| } | ||||
|  | ||||
| namespace IPC { | ||||
|  | ||||
| enum DescriptorType : u32 { | ||||
|     // Buffer related desciptors types (mask : 0x0F) | ||||
|     StaticBuffer = 0x02, | ||||
|     PXIBuffer = 0x04, | ||||
|     MappedBuffer = 0x08, | ||||
|     // Handle related descriptors types (mask : 0x30, but need to check for buffer related | ||||
|     // descriptors first ) | ||||
|     CopyHandle = 0x00, | ||||
|     MoveHandle = 0x10, | ||||
|     CallingPid = 0x20, | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * @brief Creates a command header to be used for IPC | ||||
|  * @param command_id            ID of the command to create a header for. | ||||
|  * @param normal_params         Size of the normal parameters in words. Up to 63. | ||||
|  * @param translate_params_size Size of the translate parameters in words. Up to 63. | ||||
|  * @return The created IPC header. | ||||
|  * | ||||
|  * Normal parameters are sent directly to the process while the translate parameters might go | ||||
|  * through modifications and checks by the kernel. | ||||
|  * The translate parameters are described by headers generated with the IPC::*Desc functions. | ||||
|  * | ||||
|  * @note While #normal_params is equivalent to the number of normal parameters, | ||||
|  * #translate_params_size includes the size occupied by the translate parameters headers. | ||||
|  */ | ||||
| constexpr u32 MakeHeader(u16 command_id, unsigned int normal_params, | ||||
|                          unsigned int translate_params_size) { | ||||
|     return (u32(command_id) << 16) | ((u32(normal_params) & 0x3F) << 6) | | ||||
|            (u32(translate_params_size) & 0x3F); | ||||
| } | ||||
|  | ||||
| union Header { | ||||
|     u32 raw; | ||||
|     BitField<0, 6, u32> translate_params_size; | ||||
|     BitField<6, 6, u32> normal_params; | ||||
|     BitField<16, 16, u32> command_id; | ||||
| }; | ||||
|  | ||||
| inline Header ParseHeader(u32 header) { | ||||
|     return {header}; | ||||
| } | ||||
|  | ||||
| constexpr u32 MoveHandleDesc(u32 num_handles = 1) { | ||||
|     return MoveHandle | ((num_handles - 1) << 26); | ||||
| } | ||||
|  | ||||
| constexpr u32 CopyHandleDesc(u32 num_handles = 1) { | ||||
|     return CopyHandle | ((num_handles - 1) << 26); | ||||
| } | ||||
|  | ||||
| constexpr u32 CallingPidDesc() { | ||||
|     return CallingPid; | ||||
| } | ||||
|  | ||||
| constexpr bool isHandleDescriptor(u32 descriptor) { | ||||
|     return (descriptor & 0xF) == 0x0; | ||||
| } | ||||
|  | ||||
| constexpr u32 HandleNumberFromDesc(u32 handle_descriptor) { | ||||
|     return (handle_descriptor >> 26) + 1; | ||||
| } | ||||
|  | ||||
| constexpr u32 StaticBufferDesc(u32 size, u8 buffer_id) { | ||||
|     return StaticBuffer | (size << 14) | ((buffer_id & 0xF) << 10); | ||||
| } | ||||
|  | ||||
| union StaticBufferDescInfo { | ||||
|     u32 raw; | ||||
|     BitField<10, 4, u32> buffer_id; | ||||
|     BitField<14, 18, u32> size; | ||||
| }; | ||||
|  | ||||
| inline StaticBufferDescInfo ParseStaticBufferDesc(const u32 desc) { | ||||
|     return {desc}; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @brief Creates a header describing a buffer to be sent over PXI. | ||||
|  * @param size         Size of the buffer. Max 0x00FFFFFF. | ||||
|  * @param buffer_id    The Id of the buffer. Max 0xF. | ||||
|  * @param is_read_only true if the buffer is read-only. If false, the buffer is considered to have | ||||
|  * read-write access. | ||||
|  * @return The created PXI buffer header. | ||||
|  * | ||||
|  * The next value is a phys-address of a table located in the BASE memregion. | ||||
|  */ | ||||
| inline u32 PXIBufferDesc(u32 size, unsigned buffer_id, bool is_read_only) { | ||||
|     u32 type = PXIBuffer; | ||||
|     if (is_read_only) | ||||
|         type |= 0x2; | ||||
|     return type | (size << 8) | ((buffer_id & 0xF) << 4); | ||||
| } | ||||
|  | ||||
| enum MappedBufferPermissions { | ||||
|     R = 1, | ||||
|     W = 2, | ||||
|     RW = R | W, | ||||
| }; | ||||
|  | ||||
| constexpr u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) { | ||||
|     return MappedBuffer | (size << 4) | (u32(perms) << 1); | ||||
| } | ||||
|  | ||||
| union MappedBufferDescInfo { | ||||
|     u32 raw; | ||||
|     BitField<4, 28, u32> size; | ||||
|     BitField<1, 2, MappedBufferPermissions> perms; | ||||
| }; | ||||
|  | ||||
| inline MappedBufferDescInfo ParseMappedBufferDesc(const u32 desc) { | ||||
|     return{ desc }; | ||||
| } | ||||
|  | ||||
| inline DescriptorType GetDescriptorType(u32 descriptor) { | ||||
|     // Note: Those checks must be done in this order | ||||
|     if (isHandleDescriptor(descriptor)) | ||||
|         return (DescriptorType)(descriptor & 0x30); | ||||
|  | ||||
|     // handle the fact that the following descriptors can have rights | ||||
|     if (descriptor & MappedBuffer) | ||||
|         return MappedBuffer; | ||||
|  | ||||
|     if (descriptor & PXIBuffer) | ||||
|         return PXIBuffer; | ||||
|  | ||||
|     return StaticBuffer; | ||||
| } | ||||
|  | ||||
| } // namespace IPC | ||||
| @@ -15,6 +15,9 @@ ClientPort::ClientPort() {} | ||||
| ClientPort::~ClientPort() {} | ||||
|  | ||||
| ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | ||||
|     // Note: Threads do not wait for the server endpoint to call | ||||
|     // AcceptSession before returning from this call. | ||||
|  | ||||
|     if (active_sessions >= max_sessions) { | ||||
|         return ResultCode(ErrorDescription::MaxConnectionsReached, | ||||
|                           ErrorModule::OS, ErrorSummary::WouldBlock, | ||||
| @@ -27,7 +30,7 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | ||||
|     auto client_session = std::get<SharedPtr<ClientSession>>(sessions); | ||||
|     auto server_session = std::get<SharedPtr<ServerSession>>(sessions); | ||||
|  | ||||
|     server_port->pending_sessions.push_back(server_session); | ||||
|     server_port->pending_sessions.push_back(std::move(server_session)); | ||||
|  | ||||
|     // Wake the threads waiting on the ServerPort | ||||
|     server_port->WakeupAllWaitingThreads(); | ||||
|   | ||||
| @@ -16,7 +16,7 @@ ResultVal<SharedPtr<ClientSession>> ClientSession::Create(SharedPtr<ServerSessio | ||||
|     SharedPtr<ClientSession> client_session(new ClientSession); | ||||
|  | ||||
|     client_session->name = std::move(name); | ||||
|     client_session->server_session = server_session; | ||||
|     client_session->server_session = std::move(server_session); | ||||
|     return MakeResult<SharedPtr<ClientSession>>(std::move(client_session)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -30,7 +30,7 @@ std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortP | ||||
|     SharedPtr<ClientPort> client_port(new ClientPort); | ||||
|  | ||||
|     server_port->name = name + "_Server"; | ||||
|     server_port->hle_handler = hle_handler; | ||||
|     server_port->hle_handler = std::move(hle_handler); | ||||
|     client_port->name = name + "_Client"; | ||||
|     client_port->server_port = server_port; | ||||
|     client_port->max_sessions = max_sessions; | ||||
|   | ||||
| @@ -18,7 +18,7 @@ ResultVal<SharedPtr<ServerSession>> ServerSession::Create(std::string name, std: | ||||
|  | ||||
|     server_session->name = std::move(name); | ||||
|     server_session->signaled = false; | ||||
|     server_session->hle_handler = hle_handler; | ||||
|     server_session->hle_handler = std::move(hle_handler); | ||||
|  | ||||
|     return MakeResult<SharedPtr<ServerSession>>(std::move(server_session)); | ||||
| } | ||||
| @@ -46,8 +46,9 @@ ResultCode ServerSession::HandleSyncRequest() { | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> ServerSession::CreateSessionPair(const std::string& name, std::shared_ptr<Service::SessionRequestHandler> hle_handler) { | ||||
|     auto server_session = ServerSession::Create(name + "_Server", hle_handler).MoveFrom(); | ||||
| ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, | ||||
|                                                             std::shared_ptr<Service::SessionRequestHandler> hle_handler) { | ||||
|     auto server_session = ServerSession::Create(name + "_Server", std::move(hle_handler)).MoveFrom(); | ||||
|     auto client_session = ClientSession::Create(server_session, name + "_Client").MoveFrom(); | ||||
|  | ||||
|     return std::make_tuple(std::move(server_session), std::move(client_session)); | ||||
|   | ||||
| @@ -40,12 +40,14 @@ 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 | ||||
|      * @return The created session tuple | ||||
|      */ | ||||
|     static std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> CreateSessionPair(const std::string& name = "Unknown", std::shared_ptr<Service::SessionRequestHandler> hle_handler = nullptr); | ||||
|     static SessionPair CreateSessionPair(const std::string& name = "Unknown", std::shared_ptr<Service::SessionRequestHandler> hle_handler = nullptr); | ||||
|  | ||||
|     /** | ||||
|      * Handle a sync request from the emulated application. | ||||
|   | ||||
| @@ -41,7 +41,7 @@ enum class MediaType : u32 { NAND = 0, SDMC = 1 }; | ||||
|  | ||||
| typedef u64 ArchiveHandle; | ||||
|  | ||||
| class File : public SessionRequestHandler, public std::enable_shared_from_this<File> { | ||||
| class File final : public SessionRequestHandler, public std::enable_shared_from_this<File> { | ||||
| public: | ||||
|     File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); | ||||
|     ~File(); | ||||
| @@ -58,7 +58,7 @@ protected: | ||||
|     void HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) override; | ||||
| }; | ||||
|  | ||||
| class Directory : public SessionRequestHandler { | ||||
| class Directory final : public SessionRequestHandler { | ||||
| public: | ||||
|     Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path); | ||||
|     ~Directory(); | ||||
|   | ||||
| @@ -84,6 +84,9 @@ ResultCode SessionRequestHandler::TranslateRequest(Kernel::SharedPtr<Kernel::Ser | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| Interface::~Interface() = default; | ||||
| Interface::Interface(u32 max_sessions) : max_sessions(max_sessions) { } | ||||
|  | ||||
| void Interface::HandleSyncRequestImpl(Kernel::SharedPtr<Kernel::ServerSession> server_session) { | ||||
|     // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. | ||||
|  | ||||
| @@ -123,14 +126,14 @@ static void AddNamedPort(Interface* interface_) { | ||||
|     auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), | ||||
|                                                     std::shared_ptr<Interface>(interface_)); | ||||
|     auto client_port = std::get<Kernel::SharedPtr<Kernel::ClientPort>>(ports); | ||||
|     g_kernel_named_ports.emplace(interface_->GetPortName(), client_port); | ||||
|     g_kernel_named_ports.emplace(interface_->GetPortName(), std::move(client_port)); | ||||
| } | ||||
|  | ||||
| void AddService(Interface* interface_) { | ||||
|     auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), | ||||
|                                                     std::shared_ptr<Interface>(interface_)); | ||||
|     auto client_port = std::get<Kernel::SharedPtr<Kernel::ClientPort>>(ports); | ||||
|     g_srv_services.emplace(interface_->GetPortName(), client_port); | ||||
|     g_srv_services.emplace(interface_->GetPortName(), std::move(client_port)); | ||||
| } | ||||
|  | ||||
| /// Initialize ServiceManager | ||||
|   | ||||
| @@ -9,165 +9,12 @@ | ||||
| #include <unordered_map> | ||||
| #include <boost/container/flat_map.hpp> | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/ipc.h" | ||||
| #include "core/hle/kernel/client_port.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/hle/result.h" | ||||
| #include "core/memory.h" | ||||
|  | ||||
| namespace Kernel { | ||||
| class ServerSession; | ||||
|  | ||||
| // TODO(Subv): Move these declarations out of here | ||||
| static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of header | ||||
|  | ||||
| /** | ||||
|  * Returns a pointer to the command buffer in the current thread's TLS | ||||
|  * TODO(Subv): This is not entirely correct, the command buffer should be copied from | ||||
|  * the thread's TLS to an intermediate buffer in kernel memory, and then copied again to | ||||
|  * the service handler process' memory. | ||||
|  * @param offset Optional offset into command buffer | ||||
|  * @return Pointer to command buffer | ||||
|  */ | ||||
| inline u32* GetCommandBuffer(const int offset = 0) { | ||||
|     return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + | ||||
|                                     offset); | ||||
| } | ||||
| } | ||||
|  | ||||
| // TODO(Subv): Move this namespace out of here | ||||
| namespace IPC { | ||||
|  | ||||
| enum DescriptorType : u32 { | ||||
|     // Buffer related desciptors types (mask : 0x0F) | ||||
|     StaticBuffer = 0x02, | ||||
|     PXIBuffer = 0x04, | ||||
|     MappedBuffer = 0x08, | ||||
|     // Handle related descriptors types (mask : 0x30, but need to check for buffer related | ||||
|     // descriptors first ) | ||||
|     CopyHandle = 0x00, | ||||
|     MoveHandle = 0x10, | ||||
|     CallingPid = 0x20, | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * @brief Creates a command header to be used for IPC | ||||
|  * @param command_id            ID of the command to create a header for. | ||||
|  * @param normal_params         Size of the normal parameters in words. Up to 63. | ||||
|  * @param translate_params_size Size of the translate parameters in words. Up to 63. | ||||
|  * @return The created IPC header. | ||||
|  * | ||||
|  * Normal parameters are sent directly to the process while the translate parameters might go | ||||
|  * through modifications and checks by the kernel. | ||||
|  * The translate parameters are described by headers generated with the IPC::*Desc functions. | ||||
|  * | ||||
|  * @note While #normal_params is equivalent to the number of normal parameters, | ||||
|  * #translate_params_size includes the size occupied by the translate parameters headers. | ||||
|  */ | ||||
| constexpr u32 MakeHeader(u16 command_id, unsigned int normal_params, | ||||
|                          unsigned int translate_params_size) { | ||||
|     return (u32(command_id) << 16) | ((u32(normal_params) & 0x3F) << 6) | | ||||
|            (u32(translate_params_size) & 0x3F); | ||||
| } | ||||
|  | ||||
| union Header { | ||||
|     u32 raw; | ||||
|     BitField<0, 6, u32> translate_params_size; | ||||
|     BitField<6, 6, u32> normal_params; | ||||
|     BitField<16, 16, u32> command_id; | ||||
| }; | ||||
|  | ||||
| inline Header ParseHeader(u32 header) { | ||||
|     return {header}; | ||||
| } | ||||
|  | ||||
| constexpr u32 MoveHandleDesc(u32 num_handles = 1) { | ||||
|     return MoveHandle | ((num_handles - 1) << 26); | ||||
| } | ||||
|  | ||||
| constexpr u32 CopyHandleDesc(u32 num_handles = 1) { | ||||
|     return CopyHandle | ((num_handles - 1) << 26); | ||||
| } | ||||
|  | ||||
| constexpr u32 CallingPidDesc() { | ||||
|     return CallingPid; | ||||
| } | ||||
|  | ||||
| constexpr bool isHandleDescriptor(u32 descriptor) { | ||||
|     return (descriptor & 0xF) == 0x0; | ||||
| } | ||||
|  | ||||
| constexpr u32 HandleNumberFromDesc(u32 handle_descriptor) { | ||||
|     return (handle_descriptor >> 26) + 1; | ||||
| } | ||||
|  | ||||
| constexpr u32 StaticBufferDesc(u32 size, u8 buffer_id) { | ||||
|     return StaticBuffer | (size << 14) | ((buffer_id & 0xF) << 10); | ||||
| } | ||||
|  | ||||
| union StaticBufferDescInfo { | ||||
|     u32 raw; | ||||
|     BitField<10, 4, u32> buffer_id; | ||||
|     BitField<14, 18, u32> size; | ||||
| }; | ||||
|  | ||||
| inline StaticBufferDescInfo ParseStaticBufferDesc(const u32 desc) { | ||||
|     return {desc}; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @brief Creates a header describing a buffer to be sent over PXI. | ||||
|  * @param size         Size of the buffer. Max 0x00FFFFFF. | ||||
|  * @param buffer_id    The Id of the buffer. Max 0xF. | ||||
|  * @param is_read_only true if the buffer is read-only. If false, the buffer is considered to have | ||||
|  * read-write access. | ||||
|  * @return The created PXI buffer header. | ||||
|  * | ||||
|  * The next value is a phys-address of a table located in the BASE memregion. | ||||
|  */ | ||||
| inline u32 PXIBufferDesc(u32 size, unsigned buffer_id, bool is_read_only) { | ||||
|     u32 type = PXIBuffer; | ||||
|     if (is_read_only) | ||||
|         type |= 0x2; | ||||
|     return type | (size << 8) | ((buffer_id & 0xF) << 4); | ||||
| } | ||||
|  | ||||
| enum MappedBufferPermissions { | ||||
|     R = 1, | ||||
|     W = 2, | ||||
|     RW = R | W, | ||||
| }; | ||||
|  | ||||
| constexpr u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) { | ||||
|     return MappedBuffer | (size << 4) | (u32(perms) << 1); | ||||
| } | ||||
|  | ||||
| union MappedBufferDescInfo { | ||||
|     u32 raw; | ||||
|     BitField<4, 28, u32> size; | ||||
|     BitField<1, 2, MappedBufferPermissions> perms; | ||||
| }; | ||||
|  | ||||
| inline MappedBufferDescInfo ParseMappedBufferDesc(const u32 desc) { | ||||
|     return{ desc }; | ||||
| } | ||||
|  | ||||
| inline DescriptorType GetDescriptorType(u32 descriptor) { | ||||
|     // Note: Those checks must be done in this order | ||||
|     if (isHandleDescriptor(descriptor)) | ||||
|         return (DescriptorType)(descriptor & 0x30); | ||||
|  | ||||
|     // handle the fact that the following descriptors can have rights | ||||
|     if (descriptor & MappedBuffer) | ||||
|         return MappedBuffer; | ||||
|  | ||||
|     if (descriptor & PXIBuffer) | ||||
|         return PXIBuffer; | ||||
|  | ||||
|     return StaticBuffer; | ||||
| } | ||||
|  | ||||
| } // namespace IPC | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| // Namespace Service | ||||
|  | ||||
| @@ -220,9 +67,9 @@ public: | ||||
|      * @param max_sessions Maximum number of sessions that can be | ||||
|      * connected to this service at the same time. | ||||
|      */ | ||||
|     Interface(u32 max_sessions = DefaultMaxSessions) : max_sessions(max_sessions) { } | ||||
|     Interface(u32 max_sessions = DefaultMaxSessions); | ||||
|  | ||||
|     virtual ~Interface() = default; | ||||
|     virtual ~Interface(); | ||||
|  | ||||
|     std::string GetName() const { | ||||
|         return GetPortName(); | ||||
|   | ||||
| @@ -87,12 +87,7 @@ static void GetServiceHandle(Service::Interface* self) { | ||||
|     if (it != Service::g_srv_services.end()) { | ||||
|         auto client_port = it->second; | ||||
|  | ||||
|         // Note: Threads do not wait for the server endpoint to call | ||||
|         // AcceptSession before returning from this call. | ||||
|  | ||||
|         // Connect to the port and retrieve the client endpoint of the connection Session. | ||||
|         auto client_session = client_port->Connect(); | ||||
|  | ||||
|         res = client_session.Code(); | ||||
|  | ||||
|         if (client_session.Succeeded()) { | ||||
|   | ||||
| @@ -226,19 +226,15 @@ static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) { | ||||
|  | ||||
|     auto client_port = it->second; | ||||
|  | ||||
|     // Connect to the port and retrieve the client endpoint of the connection Session. | ||||
|     SharedPtr<Kernel::ClientSession> client_session; | ||||
|     CASCADE_RESULT(client_session, client_port->Connect()); | ||||
|  | ||||
|     // Note: Threads do not wait for the server endpoint to call | ||||
|     // AcceptSession before returning from this call. | ||||
|  | ||||
|     // Return the client session | ||||
|     CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(client_session)); | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| /// Synchronize to an OS service | ||||
| /// Makes a blocking IPC call to an OS service. | ||||
| static ResultCode SendSyncRequest(Handle handle) { | ||||
|     SharedPtr<Kernel::ClientSession> session = Kernel::g_handle_table.Get<Kernel::ClientSession>(handle); | ||||
|     if (session == nullptr) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Subv
					Subv