Synchronize eventWait and _waitLoop code

This commit is contained in:
fincs 2018-12-14 17:59:54 +01:00
parent 054b8fecdc
commit fb789b52ba
2 changed files with 31 additions and 30 deletions

View File

@ -30,30 +30,34 @@ void eventLoadRemote(Event* t, Handle handle, bool autoclear)
Result eventWait(Event* t, u64 timeout)
{
Result rc;
bool has_timeout = timeout != UINT64_MAX;
u64 deadline = 0;
if (t->revent == INVALID_HANDLE)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
if (timeout != U64_MAX)
if (has_timeout)
deadline = armGetSystemTick() + armNsToTicks(timeout); // timeout: ns->ticks
do {
do {
s64 this_timeout = -1;
if (deadline) {
this_timeout = deadline - armGetSystemTick();
this_timeout = armTicksToNs(this_timeout >= 0 ? this_timeout : 0); // ticks->ns
u64 this_timeout = UINT64_MAX;
if (has_timeout) {
s64 remaining = deadline - armGetSystemTick();
this_timeout = remaining > 0 ? armTicksToNs(remaining) : 0; // ticks->ns
}
rc = svcWaitSynchronizationSingle(t->revent, this_timeout);
if (deadline && (rc & 0x3FFFFF) == 0xEA01)
return rc; // timeout.
} while (R_FAILED(rc));
if (has_timeout && R_VALUE(rc) == KERNELRESULT(TimedOut))
return rc;
} while (R_VALUE(rc) == KERNELRESULT(Cancelled));
if (R_FAILED(rc))
break;
if (t->autoclear)
rc = svcResetSignal(t->revent);
} while ((rc & 0x3FFFFF) == 0xFA01);
} while (R_VALUE(rc) == KERNELRESULT(InvalidState));
return rc;
}

View File

@ -145,39 +145,36 @@ clean_up:
return rc;
}
static Result _waitLoop(WaitImplFunc wait, s32* idx_out, void* objects, size_t num_objects, u64 timeout)
static Result _waitLoop(s32* idx_out, void* objects, size_t num_objects, u64 timeout, WaitImplFunc waitfunc)
{
Result rc;
bool has_timeout = timeout != UINT64_MAX;
u64 deadline = 0;
if (has_timeout)
deadline = armGetSystemTick() + armNsToTicks(timeout); // timeout: ns->ticks
do {
u64 cur_tick = armGetSystemTick();
rc = wait(idx_out, objects, num_objects, timeout);
rc = R_VALUE(rc);
if (rc == KERNELRESULT(Cancelled)) {
// On timer stop/start an interrupt is sent to listeners.
// It means the timer state has changed, and we should restart the wait.
// Adjust timeout..
if (timeout != -1) {
u64 time_spent = armTicksToNs(armGetSystemTick() - cur_tick);
if (time_spent < timeout)
timeout -= time_spent;
else
rc = KERNELRESULT(TimedOut);
}
u64 this_timeout = UINT64_MAX;
if (has_timeout) {
s64 remaining = deadline - armGetSystemTick();
this_timeout = remaining > 0 ? armTicksToNs(remaining) : 0; // ticks->ns
}
} while (rc == KERNELRESULT(Cancelled));
rc = waitfunc(idx_out, objects, num_objects, this_timeout);
if (has_timeout && R_VALUE(rc) == KERNELRESULT(TimedOut))
break;
} while (R_VALUE(rc) == KERNELRESULT(Cancelled));
return rc;
}
Result waitN(s32* idx_out, Waiter* objects, size_t num_objects, u64 timeout)
{
return _waitLoop((WaitImplFunc)waitImpl, idx_out, objects, num_objects, timeout);
return _waitLoop(idx_out, objects, num_objects, timeout, (WaitImplFunc)waitImpl);
}
Result waitNHandle(s32* idx_out, Handle* handles, size_t num_handles, u64 timeout)
{
return _waitLoop((WaitImplFunc)svcWaitSynchronization, idx_out, handles, num_handles, timeout);
return _waitLoop(idx_out, handles, num_handles, timeout, (WaitImplFunc)svcWaitSynchronization);
}