mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Properly remove a thread from its wait_objects' waitlist when it is awoken by a timeout.
This commit is contained in:
		
							parent
							
								
									17b29d8865
								
							
						
					
					
						commit
						406907d570
					
				@ -38,6 +38,11 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
 | 
			
		||||
        return thread->status == THREADSTATUS_RUNNING || thread->status == THREADSTATUS_READY;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // TODO(Subv): This call should be performed inside the loop below to check if an object can be
 | 
			
		||||
    // acquired by a particular thread. This is useful for things like recursive locking of Mutexes.
 | 
			
		||||
    if (ShouldWait())
 | 
			
		||||
        return nullptr;
 | 
			
		||||
 | 
			
		||||
    Thread* candidate = nullptr;
 | 
			
		||||
    s32 candidate_priority = THREADPRIO_LOWEST + 1;
 | 
			
		||||
 | 
			
		||||
@ -67,7 +72,7 @@ void WaitObject::WakeupAllWaitingThreads() {
 | 
			
		||||
                thread->wait_set_output = false;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            for (auto object : thread->wait_objects) {
 | 
			
		||||
            for (auto& object : thread->wait_objects) {
 | 
			
		||||
                object->Acquire();
 | 
			
		||||
                object->RemoveWaitingThread(thread.get());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -277,6 +277,10 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
 | 
			
		||||
 | 
			
		||||
    if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) {
 | 
			
		||||
        thread->wait_set_output = false;
 | 
			
		||||
        // Remove the thread from each of its waiting objects' waitlists
 | 
			
		||||
        for (auto& object : thread->wait_objects)
 | 
			
		||||
            object->RemoveWaitingThread(thread.get());
 | 
			
		||||
        thread->wait_objects.clear();
 | 
			
		||||
        thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS,
 | 
			
		||||
                                                        ErrorSummary::StatusChanged,
 | 
			
		||||
                                                        ErrorLevel::Info));
 | 
			
		||||
 | 
			
		||||
@ -321,7 +321,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou
 | 
			
		||||
        });
 | 
			
		||||
        if (all_available) {
 | 
			
		||||
            // We can acquire all objects right now, do so.
 | 
			
		||||
            for (auto object : objects)
 | 
			
		||||
            for (auto& object : objects)
 | 
			
		||||
                object->Acquire();
 | 
			
		||||
            // Note: In this case, the `out` parameter is not set, and retains whatever value it had before.
 | 
			
		||||
            return RESULT_SUCCESS;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user