|
|
@@ -47,21 +47,35 @@ Result ResetSignal(Core::System& system, Handle handle) {
|
|
|
R_THROW(ResultInvalidHandle);
|
|
|
}
|
|
|
|
|
|
-static Result WaitSynchronization(Core::System& system, int32_t* out_index, const Handle* handles,
|
|
|
- int32_t num_handles, int64_t timeout_ns) {
|
|
|
+/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
|
|
|
+Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 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);
|
|
|
|
|
|
// Get the synchronization context.
|
|
|
auto& kernel = system.Kernel();
|
|
|
auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
|
|
|
- std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> objs;
|
|
|
+ auto objs = GetCurrentThread(kernel).GetSynchronizationObjectBuffer();
|
|
|
+ auto handles = GetCurrentThread(kernel).GetHandleBuffer();
|
|
|
|
|
|
// Copy user handles.
|
|
|
if (num_handles > 0) {
|
|
|
+ // Ensure we can try to get the handles.
|
|
|
+ R_UNLESS(GetCurrentMemory(kernel).IsValidVirtualAddressRange(
|
|
|
+ user_handles, static_cast<u64>(sizeof(Handle) * num_handles)),
|
|
|
+ ResultInvalidPointer);
|
|
|
+
|
|
|
+ // Get the handles.
|
|
|
+ GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(),
|
|
|
+ sizeof(Handle) * num_handles);
|
|
|
+
|
|
|
// Convert the handles to objects.
|
|
|
- R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles,
|
|
|
- num_handles),
|
|
|
+ R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(
|
|
|
+ objs.data(), handles.data(), num_handles),
|
|
|
ResultInvalidHandle);
|
|
|
}
|
|
|
|
|
|
@@ -80,23 +94,6 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons
|
|
|
R_RETURN(res);
|
|
|
}
|
|
|
|
|
|
-/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
|
|
|
-Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 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::array<Handle, Svc::ArgumentHandleCountMax> handles;
|
|
|
- if (num_handles > 0) {
|
|
|
- GetCurrentMemory(system.Kernel())
|
|
|
- .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
|
|
|
Result CancelSynchronization(Core::System& system, Handle handle) {
|
|
|
LOG_TRACE(Kernel_SVC, "called handle=0x{:X}", handle);
|