kernel: add KObjectName
This commit is contained in:
		| @@ -225,6 +225,8 @@ add_library(core STATIC | |||||||
|     hle/kernel/k_memory_manager.h |     hle/kernel/k_memory_manager.h | ||||||
|     hle/kernel/k_memory_region.h |     hle/kernel/k_memory_region.h | ||||||
|     hle/kernel/k_memory_region_type.h |     hle/kernel/k_memory_region_type.h | ||||||
|  |     hle/kernel/k_object_name.cpp | ||||||
|  |     hle/kernel/k_object_name.h | ||||||
|     hle/kernel/k_page_bitmap.h |     hle/kernel/k_page_bitmap.h | ||||||
|     hle/kernel/k_page_buffer.cpp |     hle/kernel/k_page_buffer.cpp | ||||||
|     hle/kernel/k_page_buffer.h |     hle/kernel/k_page_buffer.h | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
| #include "core/hle/kernel/k_event_info.h" | #include "core/hle/kernel/k_event_info.h" | ||||||
| #include "core/hle/kernel/k_memory_layout.h" | #include "core/hle/kernel/k_memory_layout.h" | ||||||
| #include "core/hle/kernel/k_memory_manager.h" | #include "core/hle/kernel/k_memory_manager.h" | ||||||
|  | #include "core/hle/kernel/k_object_name.h" | ||||||
| #include "core/hle/kernel/k_page_buffer.h" | #include "core/hle/kernel/k_page_buffer.h" | ||||||
| #include "core/hle/kernel/k_port.h" | #include "core/hle/kernel/k_port.h" | ||||||
| #include "core/hle/kernel/k_process.h" | #include "core/hle/kernel/k_process.h" | ||||||
| @@ -49,6 +50,7 @@ namespace Kernel::Init { | |||||||
|     HANDLER(KThreadLocalPage,                                                                      \ |     HANDLER(KThreadLocalPage,                                                                      \ | ||||||
|             (SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8),             \ |             (SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8),             \ | ||||||
|             ##__VA_ARGS__)                                                                         \ |             ##__VA_ARGS__)                                                                         \ | ||||||
|  |     HANDLER(KObjectName, (SLAB_COUNT(KObjectName)), ##__VA_ARGS__)                                 \ | ||||||
|     HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__)                           \ |     HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__)                           \ | ||||||
|     HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__)                 \ |     HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__)                 \ | ||||||
|     HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__)                                           \ |     HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__)                                           \ | ||||||
|   | |||||||
							
								
								
									
										102
									
								
								src/core/hle/kernel/k_object_name.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								src/core/hle/kernel/k_object_name.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/kernel/k_object_name.h" | ||||||
|  |  | ||||||
|  | namespace Kernel { | ||||||
|  |  | ||||||
|  | KObjectNameGlobalData::KObjectNameGlobalData(KernelCore& kernel) : m_object_list_lock{kernel} {} | ||||||
|  | KObjectNameGlobalData::~KObjectNameGlobalData() = default; | ||||||
|  |  | ||||||
|  | void KObjectName::Initialize(KAutoObject* obj, const char* name) { | ||||||
|  |     // Set member variables. | ||||||
|  |     m_object = obj; | ||||||
|  |     std::strncpy(m_name.data(), name, sizeof(m_name) - 1); | ||||||
|  |     m_name[sizeof(m_name) - 1] = '\x00'; | ||||||
|  |  | ||||||
|  |     // Open a reference to the object we hold. | ||||||
|  |     m_object->Open(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool KObjectName::MatchesName(const char* name) const { | ||||||
|  |     return std::strncmp(m_name.data(), name, sizeof(m_name)) == 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result KObjectName::NewFromName(KernelCore& kernel, KAutoObject* obj, const char* name) { | ||||||
|  |     // Create a new object name. | ||||||
|  |     KObjectName* new_name = KObjectName::Allocate(kernel); | ||||||
|  |     R_UNLESS(new_name != nullptr, ResultOutOfResource); | ||||||
|  |  | ||||||
|  |     // Initialize the new name. | ||||||
|  |     new_name->Initialize(obj, name); | ||||||
|  |  | ||||||
|  |     // Check if there's an existing name. | ||||||
|  |     { | ||||||
|  |         // Get the global data. | ||||||
|  |         KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()}; | ||||||
|  |  | ||||||
|  |         // Ensure we have exclusive access to the global list. | ||||||
|  |         KScopedLightLock lk{gd.GetObjectListLock()}; | ||||||
|  |  | ||||||
|  |         // If the object doesn't exist, put it into the list. | ||||||
|  |         KScopedAutoObject existing_object = FindImpl(kernel, name); | ||||||
|  |         if (existing_object.IsNull()) { | ||||||
|  |             gd.GetObjectList().push_back(*new_name); | ||||||
|  |             R_SUCCEED(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // The object already exists, which is an error condition. Perform cleanup. | ||||||
|  |     obj->Close(); | ||||||
|  |     KObjectName::Free(kernel, new_name); | ||||||
|  |     R_THROW(ResultInvalidState); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result KObjectName::Delete(KernelCore& kernel, KAutoObject* obj, const char* compare_name) { | ||||||
|  |     // Get the global data. | ||||||
|  |     KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()}; | ||||||
|  |  | ||||||
|  |     // Ensure we have exclusive access to the global list. | ||||||
|  |     KScopedLightLock lk{gd.GetObjectListLock()}; | ||||||
|  |  | ||||||
|  |     // Find a matching entry in the list, and delete it. | ||||||
|  |     for (auto& name : gd.GetObjectList()) { | ||||||
|  |         if (name.MatchesName(compare_name) && obj == name.GetObject()) { | ||||||
|  |             // We found a match, clean up its resources. | ||||||
|  |             obj->Close(); | ||||||
|  |             gd.GetObjectList().erase(gd.GetObjectList().iterator_to(name)); | ||||||
|  |             KObjectName::Free(kernel, std::addressof(name)); | ||||||
|  |             R_SUCCEED(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // We didn't find the object in the list. | ||||||
|  |     R_THROW(ResultNotFound); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | KScopedAutoObject<KAutoObject> KObjectName::Find(KernelCore& kernel, const char* name) { | ||||||
|  |     // Get the global data. | ||||||
|  |     KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()}; | ||||||
|  |  | ||||||
|  |     // Ensure we have exclusive access to the global list. | ||||||
|  |     KScopedLightLock lk{gd.GetObjectListLock()}; | ||||||
|  |  | ||||||
|  |     return FindImpl(kernel, name); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | KScopedAutoObject<KAutoObject> KObjectName::FindImpl(KernelCore& kernel, const char* compare_name) { | ||||||
|  |     // Get the global data. | ||||||
|  |     KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()}; | ||||||
|  |  | ||||||
|  |     // Try to find a matching object in the global list. | ||||||
|  |     for (const auto& name : gd.GetObjectList()) { | ||||||
|  |         if (name.MatchesName(compare_name)) { | ||||||
|  |             return name.GetObject(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // There's no matching entry in the list. | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Kernel | ||||||
							
								
								
									
										86
									
								
								src/core/hle/kernel/k_object_name.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/core/hle/kernel/k_object_name.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <array> | ||||||
|  | #include <memory> | ||||||
|  | #include <boost/intrusive/list.hpp> | ||||||
|  |  | ||||||
|  | #include "core/hle/kernel/k_light_lock.h" | ||||||
|  | #include "core/hle/kernel/slab_helpers.h" | ||||||
|  | #include "core/hle/kernel/svc_results.h" | ||||||
|  |  | ||||||
|  | namespace Kernel { | ||||||
|  |  | ||||||
|  | class KObjectNameGlobalData; | ||||||
|  |  | ||||||
|  | class KObjectName : public KSlabAllocated<KObjectName>, public boost::intrusive::list_base_hook<> { | ||||||
|  | public: | ||||||
|  |     explicit KObjectName(KernelCore&) {} | ||||||
|  |     virtual ~KObjectName() = default; | ||||||
|  |  | ||||||
|  |     static constexpr size_t NameLengthMax = 12; | ||||||
|  |     using List = boost::intrusive::list<KObjectName>; | ||||||
|  |  | ||||||
|  |     static Result NewFromName(KernelCore& kernel, KAutoObject* obj, const char* name); | ||||||
|  |     static Result Delete(KernelCore& kernel, KAutoObject* obj, const char* name); | ||||||
|  |  | ||||||
|  |     static KScopedAutoObject<KAutoObject> Find(KernelCore& kernel, const char* name); | ||||||
|  |  | ||||||
|  |     template <typename Derived> | ||||||
|  |     static Result Delete(KernelCore& kernel, const char* name) { | ||||||
|  |         // Find the object. | ||||||
|  |         KScopedAutoObject obj = Find(kernel, name); | ||||||
|  |         R_UNLESS(obj.IsNotNull(), ResultNotFound); | ||||||
|  |  | ||||||
|  |         // Cast the object to the desired type. | ||||||
|  |         Derived* derived = obj->DynamicCast<Derived*>(); | ||||||
|  |         R_UNLESS(derived != nullptr, ResultNotFound); | ||||||
|  |  | ||||||
|  |         // Check that the object is closed. | ||||||
|  |         R_UNLESS(derived->IsServerClosed(), ResultInvalidState); | ||||||
|  |  | ||||||
|  |         return Delete(kernel, obj.GetPointerUnsafe(), name); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     template <typename Derived> | ||||||
|  |         requires(std::derived_from<Derived, KAutoObject>) | ||||||
|  |     static KScopedAutoObject<Derived> Find(KernelCore& kernel, const char* name) { | ||||||
|  |         return Find(kernel, name); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     static KScopedAutoObject<KAutoObject> FindImpl(KernelCore& kernel, const char* name); | ||||||
|  |  | ||||||
|  |     void Initialize(KAutoObject* obj, const char* name); | ||||||
|  |  | ||||||
|  |     bool MatchesName(const char* name) const; | ||||||
|  |     KAutoObject* GetObject() const { | ||||||
|  |         return m_object; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     std::array<char, NameLengthMax> m_name{}; | ||||||
|  |     KAutoObject* m_object{}; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class KObjectNameGlobalData { | ||||||
|  | public: | ||||||
|  |     explicit KObjectNameGlobalData(KernelCore& kernel); | ||||||
|  |     ~KObjectNameGlobalData(); | ||||||
|  |  | ||||||
|  |     KLightLock& GetObjectListLock() { | ||||||
|  |         return m_object_list_lock; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     KObjectName::List& GetObjectList() { | ||||||
|  |         return m_object_list; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     KLightLock m_object_list_lock; | ||||||
|  |     KObjectName::List m_object_list; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } // namespace Kernel | ||||||
| @@ -29,6 +29,7 @@ | |||||||
| #include "core/hle/kernel/k_hardware_timer.h" | #include "core/hle/kernel/k_hardware_timer.h" | ||||||
| #include "core/hle/kernel/k_memory_layout.h" | #include "core/hle/kernel/k_memory_layout.h" | ||||||
| #include "core/hle/kernel/k_memory_manager.h" | #include "core/hle/kernel/k_memory_manager.h" | ||||||
|  | #include "core/hle/kernel/k_object_name.h" | ||||||
| #include "core/hle/kernel/k_page_buffer.h" | #include "core/hle/kernel/k_page_buffer.h" | ||||||
| #include "core/hle/kernel/k_process.h" | #include "core/hle/kernel/k_process.h" | ||||||
| #include "core/hle/kernel/k_resource_limit.h" | #include "core/hle/kernel/k_resource_limit.h" | ||||||
| @@ -84,6 +85,7 @@ struct KernelCore::Impl { | |||||||
|         InitializeShutdownThreads(); |         InitializeShutdownThreads(); | ||||||
|         InitializePhysicalCores(); |         InitializePhysicalCores(); | ||||||
|         InitializePreemption(kernel); |         InitializePreemption(kernel); | ||||||
|  |         InitializeGlobalData(kernel); | ||||||
|  |  | ||||||
|         // Initialize the Dynamic Slab Heaps. |         // Initialize the Dynamic Slab Heaps. | ||||||
|         { |         { | ||||||
| @@ -194,6 +196,8 @@ struct KernelCore::Impl { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         object_name_global_data.reset(); | ||||||
|  |  | ||||||
|         // Ensure that the object list container is finalized and properly shutdown. |         // Ensure that the object list container is finalized and properly shutdown. | ||||||
|         global_object_list_container->Finalize(); |         global_object_list_container->Finalize(); | ||||||
|         global_object_list_container.reset(); |         global_object_list_container.reset(); | ||||||
| @@ -363,6 +367,10 @@ struct KernelCore::Impl { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     void InitializeGlobalData(KernelCore& kernel) { | ||||||
|  |         object_name_global_data = std::make_unique<KObjectNameGlobalData>(kernel); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     void MakeApplicationProcess(KProcess* process) { |     void MakeApplicationProcess(KProcess* process) { | ||||||
|         application_process = process; |         application_process = process; | ||||||
|     } |     } | ||||||
| @@ -838,6 +846,8 @@ struct KernelCore::Impl { | |||||||
|  |  | ||||||
|     std::unique_ptr<KAutoObjectWithListContainer> global_object_list_container; |     std::unique_ptr<KAutoObjectWithListContainer> global_object_list_container; | ||||||
|  |  | ||||||
|  |     std::unique_ptr<KObjectNameGlobalData> object_name_global_data; | ||||||
|  |  | ||||||
|     /// Map of named ports managed by the kernel, which can be retrieved using |     /// Map of named ports managed by the kernel, which can be retrieved using | ||||||
|     /// the ConnectToPort SVC. |     /// the ConnectToPort SVC. | ||||||
|     std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory; |     std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory; | ||||||
| @@ -1138,6 +1148,10 @@ void KernelCore::SetCurrentEmuThread(KThread* thread) { | |||||||
|     impl->SetCurrentEmuThread(thread); |     impl->SetCurrentEmuThread(thread); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | KObjectNameGlobalData& KernelCore::ObjectNameGlobalData() { | ||||||
|  |     return *impl->object_name_global_data; | ||||||
|  | } | ||||||
|  |  | ||||||
| KMemoryManager& KernelCore::MemoryManager() { | KMemoryManager& KernelCore::MemoryManager() { | ||||||
|     return *impl->memory_manager; |     return *impl->memory_manager; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -44,6 +44,8 @@ class KHardwareTimer; | |||||||
| class KLinkedListNode; | class KLinkedListNode; | ||||||
| class KMemoryLayout; | class KMemoryLayout; | ||||||
| class KMemoryManager; | class KMemoryManager; | ||||||
|  | class KObjectName; | ||||||
|  | class KObjectNameGlobalData; | ||||||
| class KPageBuffer; | class KPageBuffer; | ||||||
| class KPageBufferSlabHeap; | class KPageBufferSlabHeap; | ||||||
| class KPort; | class KPort; | ||||||
| @@ -240,6 +242,9 @@ public: | |||||||
|     /// Register the current thread as a non CPU core thread. |     /// Register the current thread as a non CPU core thread. | ||||||
|     void RegisterHostThread(KThread* existing_thread = nullptr); |     void RegisterHostThread(KThread* existing_thread = nullptr); | ||||||
|  |  | ||||||
|  |     /// Gets global data for KObjectName. | ||||||
|  |     KObjectNameGlobalData& ObjectNameGlobalData(); | ||||||
|  |  | ||||||
|     /// Gets the virtual memory manager for the kernel. |     /// Gets the virtual memory manager for the kernel. | ||||||
|     KMemoryManager& MemoryManager(); |     KMemoryManager& MemoryManager(); | ||||||
|  |  | ||||||
| @@ -372,6 +377,8 @@ public: | |||||||
|             return slab_heap_container->page_buffer; |             return slab_heap_container->page_buffer; | ||||||
|         } else if constexpr (std::is_same_v<T, KThreadLocalPage>) { |         } else if constexpr (std::is_same_v<T, KThreadLocalPage>) { | ||||||
|             return slab_heap_container->thread_local_page; |             return slab_heap_container->thread_local_page; | ||||||
|  |         } else if constexpr (std::is_same_v<T, KObjectName>) { | ||||||
|  |             return slab_heap_container->object_name; | ||||||
|         } else if constexpr (std::is_same_v<T, KSessionRequest>) { |         } else if constexpr (std::is_same_v<T, KSessionRequest>) { | ||||||
|             return slab_heap_container->session_request; |             return slab_heap_container->session_request; | ||||||
|         } else if constexpr (std::is_same_v<T, KSecureSystemResource>) { |         } else if constexpr (std::is_same_v<T, KSecureSystemResource>) { | ||||||
| @@ -443,6 +450,7 @@ private: | |||||||
|         KSlabHeap<KDeviceAddressSpace> device_address_space; |         KSlabHeap<KDeviceAddressSpace> device_address_space; | ||||||
|         KSlabHeap<KPageBuffer> page_buffer; |         KSlabHeap<KPageBuffer> page_buffer; | ||||||
|         KSlabHeap<KThreadLocalPage> thread_local_page; |         KSlabHeap<KThreadLocalPage> thread_local_page; | ||||||
|  |         KSlabHeap<KObjectName> object_name; | ||||||
|         KSlabHeap<KSessionRequest> session_request; |         KSlabHeap<KSessionRequest> session_request; | ||||||
|         KSlabHeap<KSecureSystemResource> secure_system_resource; |         KSlabHeap<KSecureSystemResource> secure_system_resource; | ||||||
|         KSlabHeap<KEventInfo> event_info; |         KSlabHeap<KEventInfo> event_info; | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/hle/kernel/k_client_port.h" | #include "core/hle/kernel/k_client_port.h" | ||||||
| #include "core/hle/kernel/k_client_session.h" | #include "core/hle/kernel/k_client_session.h" | ||||||
|  | #include "core/hle/kernel/k_object_name.h" | ||||||
| #include "core/hle/kernel/k_port.h" | #include "core/hle/kernel/k_port.h" | ||||||
| #include "core/hle/kernel/k_process.h" | #include "core/hle/kernel/k_process.h" | ||||||
| #include "core/hle/kernel/svc.h" | #include "core/hle/kernel/svc.h" | ||||||
| @@ -74,10 +75,57 @@ Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) { | |||||||
|     R_THROW(ResultNotImplemented); |     R_THROW(ResultNotImplemented); | ||||||
| } | } | ||||||
|  |  | ||||||
| Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t name, | Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, | ||||||
|                        int32_t max_sessions) { |                        int32_t max_sessions) { | ||||||
|     UNIMPLEMENTED(); |     // Copy the provided name from user memory to kernel memory. | ||||||
|     R_THROW(ResultNotImplemented); |     std::array<char, KObjectName::NameLengthMax> name{}; | ||||||
|  |     system.Memory().ReadBlock(user_name, name.data(), sizeof(name)); | ||||||
|  |  | ||||||
|  |     // Validate that sessions and name are valid. | ||||||
|  |     R_UNLESS(max_sessions >= 0, ResultOutOfRange); | ||||||
|  |     R_UNLESS(name[sizeof(name) - 1] == '\x00', ResultOutOfRange); | ||||||
|  |  | ||||||
|  |     if (max_sessions > 0) { | ||||||
|  |         // Get the current handle table. | ||||||
|  |         auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable(); | ||||||
|  |  | ||||||
|  |         // Create a new port. | ||||||
|  |         KPort* port = KPort::Create(system.Kernel()); | ||||||
|  |         R_UNLESS(port != nullptr, ResultOutOfResource); | ||||||
|  |  | ||||||
|  |         // Initialize the new port. | ||||||
|  |         port->Initialize(max_sessions, false, ""); | ||||||
|  |  | ||||||
|  |         // Register the port. | ||||||
|  |         KPort::Register(system.Kernel(), port); | ||||||
|  |  | ||||||
|  |         // Ensure that our only reference to the port is in the handle table when we're done. | ||||||
|  |         SCOPE_EXIT({ | ||||||
|  |             port->GetClientPort().Close(); | ||||||
|  |             port->GetServerPort().Close(); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         // Register the handle in the table. | ||||||
|  |         R_TRY(handle_table.Add(out_server_handle, std::addressof(port->GetServerPort()))); | ||||||
|  |         ON_RESULT_FAILURE { | ||||||
|  |             handle_table.Remove(*out_server_handle); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         // Create a new object name. | ||||||
|  |         R_TRY(KObjectName::NewFromName(system.Kernel(), std::addressof(port->GetClientPort()), | ||||||
|  |                                        name.data())); | ||||||
|  |     } else /* if (max_sessions == 0) */ { | ||||||
|  |         // Ensure that this else case is correct. | ||||||
|  |         ASSERT(max_sessions == 0); | ||||||
|  |  | ||||||
|  |         // If we're closing, there's no server handle. | ||||||
|  |         *out_server_handle = InvalidHandle; | ||||||
|  |  | ||||||
|  |         // Delete the object. | ||||||
|  |         R_TRY(KObjectName::Delete<KClientPort>(system.Kernel(), name.data())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     R_SUCCEED(); | ||||||
| } | } | ||||||
|  |  | ||||||
| Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name) { | Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user