svc: Move most process termination code to its own function within Process
Reduces the use of Process class members externally and keeps most code related to tearing down a process with the rest of the process code.
This commit is contained in:
		@@ -7,10 +7,12 @@
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/common_funcs.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/kernel/errors.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/process.h"
 | 
			
		||||
#include "core/hle/kernel/resource_limit.h"
 | 
			
		||||
#include "core/hle/kernel/scheduler.h"
 | 
			
		||||
#include "core/hle/kernel/thread.h"
 | 
			
		||||
#include "core/hle/kernel/vm_manager.h"
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
@@ -128,6 +130,33 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
 | 
			
		||||
    Kernel::SetupMainThread(kernel, entry_point, main_thread_priority, *this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Process::PrepareForTermination() {
 | 
			
		||||
    status = ProcessStatus::Exited;
 | 
			
		||||
 | 
			
		||||
    const auto stop_threads = [this](const std::vector<SharedPtr<Thread>>& thread_list) {
 | 
			
		||||
        for (auto& thread : thread_list) {
 | 
			
		||||
            if (thread->owner_process != this)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            if (thread == GetCurrentThread())
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            // TODO(Subv): When are the other running/ready threads terminated?
 | 
			
		||||
            ASSERT_MSG(thread->status == ThreadStatus::WaitSynchAny ||
 | 
			
		||||
                           thread->status == ThreadStatus::WaitSynchAll,
 | 
			
		||||
                       "Exiting processes with non-waiting threads is currently unimplemented");
 | 
			
		||||
 | 
			
		||||
            thread->Stop();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    auto& system = Core::System::GetInstance();
 | 
			
		||||
    stop_threads(system.Scheduler(0)->GetThreadList());
 | 
			
		||||
    stop_threads(system.Scheduler(1)->GetThreadList());
 | 
			
		||||
    stop_threads(system.Scheduler(2)->GetThreadList());
 | 
			
		||||
    stop_threads(system.Scheduler(3)->GetThreadList());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finds a free location for the TLS section of a thread.
 | 
			
		||||
 * @param tls_slots The TLS page array of the thread's owner process.
 | 
			
		||||
 
 | 
			
		||||
@@ -131,6 +131,16 @@ public:
 | 
			
		||||
        return HANDLE_TYPE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Gets the current status of the process
 | 
			
		||||
    ProcessStatus GetStatus() const {
 | 
			
		||||
        return status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Gets the unique ID that identifies this particular process.
 | 
			
		||||
    u32 GetProcessID() const {
 | 
			
		||||
        return process_id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Title ID corresponding to the process
 | 
			
		||||
    u64 program_id;
 | 
			
		||||
 | 
			
		||||
@@ -154,11 +164,6 @@ public:
 | 
			
		||||
    u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK;
 | 
			
		||||
    u32 allowed_thread_priority_mask = 0xFFFFFFFF;
 | 
			
		||||
    u32 is_virtual_address_memory_enabled = 0;
 | 
			
		||||
    /// Current status of the process
 | 
			
		||||
    ProcessStatus status;
 | 
			
		||||
 | 
			
		||||
    /// The ID of this process
 | 
			
		||||
    u32 process_id = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them
 | 
			
		||||
@@ -171,6 +176,12 @@ public:
 | 
			
		||||
     */
 | 
			
		||||
    void Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Prepares a process for termination by stopping all of its threads
 | 
			
		||||
     * and clearing any other resources.
 | 
			
		||||
     */
 | 
			
		||||
    void PrepareForTermination();
 | 
			
		||||
 | 
			
		||||
    void LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr);
 | 
			
		||||
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -195,6 +206,12 @@ private:
 | 
			
		||||
    explicit Process(KernelCore& kernel);
 | 
			
		||||
    ~Process() override;
 | 
			
		||||
 | 
			
		||||
    /// Current status of the process
 | 
			
		||||
    ProcessStatus status;
 | 
			
		||||
 | 
			
		||||
    /// The ID of this process
 | 
			
		||||
    u32 process_id = 0;
 | 
			
		||||
 | 
			
		||||
    // Memory used to back the allocations in the regular heap. A single vector is used to cover
 | 
			
		||||
    // the entire virtual address space extents that bound the allocations, including any holes.
 | 
			
		||||
    // This makes deallocation and reallocation of holes fast and keeps process memory contiguous
 | 
			
		||||
 
 | 
			
		||||
@@ -169,7 +169,7 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
 | 
			
		||||
        return ERR_INVALID_HANDLE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *process_id = process->process_id;
 | 
			
		||||
    *process_id = process->GetProcessID();
 | 
			
		||||
    return RESULT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -530,35 +530,13 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAdd
 | 
			
		||||
 | 
			
		||||
/// Exits the current process
 | 
			
		||||
static void ExitProcess() {
 | 
			
		||||
    LOG_INFO(Kernel_SVC, "Process {} exiting", Core::CurrentProcess()->process_id);
 | 
			
		||||
    auto& current_process = Core::CurrentProcess();
 | 
			
		||||
 | 
			
		||||
    ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running,
 | 
			
		||||
    LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID());
 | 
			
		||||
    ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running,
 | 
			
		||||
               "Process has already exited");
 | 
			
		||||
 | 
			
		||||
    Core::CurrentProcess()->status = ProcessStatus::Exited;
 | 
			
		||||
 | 
			
		||||
    auto stop_threads = [](const std::vector<SharedPtr<Thread>>& thread_list) {
 | 
			
		||||
        for (auto& thread : thread_list) {
 | 
			
		||||
            if (thread->owner_process != Core::CurrentProcess())
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            if (thread == GetCurrentThread())
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            // TODO(Subv): When are the other running/ready threads terminated?
 | 
			
		||||
            ASSERT_MSG(thread->status == ThreadStatus::WaitSynchAny ||
 | 
			
		||||
                           thread->status == ThreadStatus::WaitSynchAll,
 | 
			
		||||
                       "Exiting processes with non-waiting threads is currently unimplemented");
 | 
			
		||||
 | 
			
		||||
            thread->Stop();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    auto& system = Core::System::GetInstance();
 | 
			
		||||
    stop_threads(system.Scheduler(0)->GetThreadList());
 | 
			
		||||
    stop_threads(system.Scheduler(1)->GetThreadList());
 | 
			
		||||
    stop_threads(system.Scheduler(2)->GetThreadList());
 | 
			
		||||
    stop_threads(system.Scheduler(3)->GetThreadList());
 | 
			
		||||
    current_process->PrepareForTermination();
 | 
			
		||||
 | 
			
		||||
    // Kill the current thread
 | 
			
		||||
    GetCurrentThread()->Stop();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user