mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	Merge pull request #9904 from liamwhite/ws
kernel: fix WaitSynchronization
This commit is contained in:
		@@ -48,19 +48,15 @@ Result ResetSignal(Core::System& system, Handle handle) {
 | 
				
			|||||||
    return ResultInvalidHandle;
 | 
					    return ResultInvalidHandle;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
 | 
					static Result WaitSynchronization(Core::System& system, int32_t* out_index, const Handle* handles,
 | 
				
			||||||
Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, s32 num_handles,
 | 
					                                  int32_t num_handles, int64_t timeout_ns) {
 | 
				
			||||||
                           s64 nano_seconds) {
 | 
					 | 
				
			||||||
    LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, num_handles={}, nano_seconds={}",
 | 
					 | 
				
			||||||
              handles_address, num_handles, nano_seconds);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Ensure number of handles is valid.
 | 
					    // Ensure number of handles is valid.
 | 
				
			||||||
    R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange);
 | 
					    R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get the synchronization context.
 | 
				
			||||||
    auto& kernel = system.Kernel();
 | 
					    auto& kernel = system.Kernel();
 | 
				
			||||||
 | 
					    auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
 | 
				
			||||||
    std::vector<KSynchronizationObject*> objs(num_handles);
 | 
					    std::vector<KSynchronizationObject*> objs(num_handles);
 | 
				
			||||||
    const auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
 | 
					 | 
				
			||||||
    Handle* handles = system.Memory().GetPointer<Handle>(handles_address);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Copy user handles.
 | 
					    // Copy user handles.
 | 
				
			||||||
    if (num_handles > 0) {
 | 
					    if (num_handles > 0) {
 | 
				
			||||||
@@ -68,21 +64,38 @@ Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_addre
 | 
				
			|||||||
        R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles,
 | 
					        R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles,
 | 
				
			||||||
                                                                         num_handles),
 | 
					                                                                         num_handles),
 | 
				
			||||||
                 ResultInvalidHandle);
 | 
					                 ResultInvalidHandle);
 | 
				
			||||||
        for (const auto& obj : objs) {
 | 
					 | 
				
			||||||
            kernel.RegisterInUseObject(obj);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Ensure handles are closed when we're done.
 | 
					    // Ensure handles are closed when we're done.
 | 
				
			||||||
    SCOPE_EXIT({
 | 
					    SCOPE_EXIT({
 | 
				
			||||||
        for (s32 i = 0; i < num_handles; ++i) {
 | 
					        for (auto i = 0; i < num_handles; ++i) {
 | 
				
			||||||
            kernel.UnregisterInUseObject(objs[i]);
 | 
					 | 
				
			||||||
            objs[i]->Close();
 | 
					            objs[i]->Close();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return KSynchronizationObject::Wait(kernel, index, objs.data(), static_cast<s32>(objs.size()),
 | 
					    // Wait on the objects.
 | 
				
			||||||
                                        nano_seconds);
 | 
					    Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(),
 | 
				
			||||||
 | 
					                                              static_cast<s32>(objs.size()), timeout_ns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    R_SUCCEED_IF(res == ResultSessionClosed);
 | 
				
			||||||
 | 
					    R_RETURN(res);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
 | 
				
			||||||
 | 
					Result WaitSynchronization(Core::System& system, int32_t* out_index, VAddr user_handles,
 | 
				
			||||||
 | 
					                           int32_t num_handles, int64_t timeout_ns) {
 | 
				
			||||||
 | 
					    LOG_TRACE(Kernel_SVC, "called user_handles={:#x}, num_handles={}, timeout_ns={}", user_handles,
 | 
				
			||||||
 | 
					              num_handles, timeout_ns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Ensure number of handles is valid.
 | 
				
			||||||
 | 
					    R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<Handle> handles(num_handles);
 | 
				
			||||||
 | 
					    if (num_handles > 0) {
 | 
				
			||||||
 | 
					        system.Memory().ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    R_RETURN(WaitSynchronization(system, out_index, handles.data(), num_handles, timeout_ns));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Resumes a thread waiting on WaitSynchronization
 | 
					/// Resumes a thread waiting on WaitSynchronization
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user