diff options
| author | 2021-07-02 15:19:04 -0700 | |
|---|---|---|
| committer | 2021-07-20 18:54:56 -0700 | |
| commit | 52caa52cc2e47d426b5af38fd8439da237836e0e (patch) | |
| tree | 1412e9e92f8f3f1bd67d2d237234d149011a55d2 /src/core/hle/kernel/kernel.cpp | |
| parent | hle: kernel: KProcess: Change process termination assert to a warning. (diff) | |
| download | yuzu-52caa52cc2e47d426b5af38fd8439da237836e0e.tar.gz yuzu-52caa52cc2e47d426b5af38fd8439da237836e0e.tar.xz yuzu-52caa52cc2e47d426b5af38fd8439da237836e0e.zip | |
hle: kernel: Track and release server sessions, and protect methods with locks.
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 78 |
1 files changed, 66 insertions, 12 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 2d5525839..92fbc5532 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -91,15 +91,39 @@ struct KernelCore::Impl { | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | void Shutdown() { | 93 | void Shutdown() { |
| 94 | // Shutdown all processes. | ||
| 94 | if (current_process) { | 95 | if (current_process) { |
| 95 | current_process->Finalize(); | 96 | current_process->Finalize(); |
| 96 | current_process->Close(); | 97 | current_process->Close(); |
| 97 | current_process = nullptr; | 98 | current_process = nullptr; |
| 98 | } | 99 | } |
| 99 | |||
| 100 | process_list.clear(); | 100 | process_list.clear(); |
| 101 | 101 | ||
| 102 | // Ensures all service threads gracefully shutdown | 102 | // Close all open server ports. |
| 103 | std::unordered_set<KServerPort*> server_ports_; | ||
| 104 | { | ||
| 105 | std::lock_guard lk(server_ports_lock); | ||
| 106 | server_ports_ = server_ports; | ||
| 107 | server_ports.clear(); | ||
| 108 | } | ||
| 109 | for (auto* server_port : server_ports_) { | ||
| 110 | server_port->Close(); | ||
| 111 | } | ||
| 112 | // Close all open server sessions. | ||
| 113 | std::unordered_set<KServerSession*> server_sessions_; | ||
| 114 | { | ||
| 115 | std::lock_guard lk(server_sessions_lock); | ||
| 116 | server_sessions_ = server_sessions; | ||
| 117 | server_sessions.clear(); | ||
| 118 | } | ||
| 119 | for (auto* server_session : server_sessions_) { | ||
| 120 | server_session->Close(); | ||
| 121 | } | ||
| 122 | |||
| 123 | // Ensure that the object list container is finalized and properly shutdown. | ||
| 124 | object_list_container.Finalize(); | ||
| 125 | |||
| 126 | // Ensures all service threads gracefully shutdown. | ||
| 103 | service_threads.clear(); | 127 | service_threads.clear(); |
| 104 | 128 | ||
| 105 | next_object_id = 0; | 129 | next_object_id = 0; |
| @@ -147,10 +171,13 @@ struct KernelCore::Impl { | |||
| 147 | next_host_thread_id = Core::Hardware::NUM_CPU_CORES; | 171 | next_host_thread_id = Core::Hardware::NUM_CPU_CORES; |
| 148 | 172 | ||
| 149 | // Track kernel objects that were not freed on shutdown | 173 | // Track kernel objects that were not freed on shutdown |
| 150 | if (registered_objects.size()) { | 174 | { |
| 151 | LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!", | 175 | std::lock_guard lk(registered_objects_lock); |
| 152 | registered_objects.size()); | 176 | if (registered_objects.size()) { |
| 153 | registered_objects.clear(); | 177 | LOG_WARNING(Kernel, "{} kernel objects were dangling on shutdown!", |
| 178 | registered_objects.size()); | ||
| 179 | registered_objects.clear(); | ||
| 180 | } | ||
| 154 | } | 181 | } |
| 155 | } | 182 | } |
| 156 | 183 | ||
| @@ -640,6 +667,21 @@ struct KernelCore::Impl { | |||
| 640 | user_slab_heap_size); | 667 | user_slab_heap_size); |
| 641 | } | 668 | } |
| 642 | 669 | ||
| 670 | KClientPort* CreateNamedServicePort(std::string name) { | ||
| 671 | auto search = service_interface_factory.find(name); | ||
| 672 | if (search == service_interface_factory.end()) { | ||
| 673 | UNIMPLEMENTED(); | ||
| 674 | return {}; | ||
| 675 | } | ||
| 676 | |||
| 677 | KClientPort* port = &search->second(system.ServiceManager(), system); | ||
| 678 | { | ||
| 679 | std::lock_guard lk(server_ports_lock); | ||
| 680 | server_ports.insert(&port->GetParent()->GetServerPort()); | ||
| 681 | } | ||
| 682 | return port; | ||
| 683 | } | ||
| 684 | |||
| 643 | std::atomic<u32> next_object_id{0}; | 685 | std::atomic<u32> next_object_id{0}; |
| 644 | std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; | 686 | std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; |
| 645 | std::atomic<u64> next_user_process_id{KProcess::ProcessIDMin}; | 687 | std::atomic<u64> next_user_process_id{KProcess::ProcessIDMin}; |
| @@ -666,7 +708,12 @@ struct KernelCore::Impl { | |||
| 666 | /// the ConnectToPort SVC. | 708 | /// the ConnectToPort SVC. |
| 667 | std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory; | 709 | std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory; |
| 668 | NamedPortTable named_ports; | 710 | NamedPortTable named_ports; |
| 711 | std::unordered_set<KServerPort*> server_ports; | ||
| 712 | std::unordered_set<KServerSession*> server_sessions; | ||
| 669 | std::unordered_set<KAutoObject*> registered_objects; | 713 | std::unordered_set<KAutoObject*> registered_objects; |
| 714 | std::mutex server_ports_lock; | ||
| 715 | std::mutex server_sessions_lock; | ||
| 716 | std::mutex registered_objects_lock; | ||
| 670 | 717 | ||
| 671 | std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; | 718 | std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; |
| 672 | std::vector<Kernel::PhysicalCore> cores; | 719 | std::vector<Kernel::PhysicalCore> cores; |
| @@ -855,19 +902,26 @@ void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory& | |||
| 855 | } | 902 | } |
| 856 | 903 | ||
| 857 | KClientPort* KernelCore::CreateNamedServicePort(std::string name) { | 904 | KClientPort* KernelCore::CreateNamedServicePort(std::string name) { |
| 858 | auto search = impl->service_interface_factory.find(name); | 905 | return impl->CreateNamedServicePort(std::move(name)); |
| 859 | if (search == impl->service_interface_factory.end()) { | 906 | } |
| 860 | UNIMPLEMENTED(); | 907 | |
| 861 | return {}; | 908 | void KernelCore::RegisterServerSession(KServerSession* server_session) { |
| 862 | } | 909 | std::lock_guard lk(impl->server_sessions_lock); |
| 863 | return &search->second(impl->system.ServiceManager(), impl->system); | 910 | impl->server_sessions.insert(server_session); |
| 911 | } | ||
| 912 | |||
| 913 | void KernelCore::UnregisterServerSession(KServerSession* server_session) { | ||
| 914 | std::lock_guard lk(impl->server_sessions_lock); | ||
| 915 | impl->server_sessions.erase(server_session); | ||
| 864 | } | 916 | } |
| 865 | 917 | ||
| 866 | void KernelCore::RegisterKernelObject(KAutoObject* object) { | 918 | void KernelCore::RegisterKernelObject(KAutoObject* object) { |
| 919 | std::lock_guard lk(impl->registered_objects_lock); | ||
| 867 | impl->registered_objects.insert(object); | 920 | impl->registered_objects.insert(object); |
| 868 | } | 921 | } |
| 869 | 922 | ||
| 870 | void KernelCore::UnregisterKernelObject(KAutoObject* object) { | 923 | void KernelCore::UnregisterKernelObject(KAutoObject* object) { |
| 924 | std::lock_guard lk(impl->registered_objects_lock); | ||
| 871 | impl->registered_objects.erase(object); | 925 | impl->registered_objects.erase(object); |
| 872 | } | 926 | } |
| 873 | 927 | ||