mirror of
https://github.com/switchbrew/libnx.git
synced 2025-07-06 19:32:15 +02:00
Synchronize eventWait and _waitLoop code
This commit is contained in:
parent
054b8fecdc
commit
fb789b52ba
@ -30,30 +30,34 @@ void eventLoadRemote(Event* t, Handle handle, bool autoclear)
|
|||||||
Result eventWait(Event* t, u64 timeout)
|
Result eventWait(Event* t, u64 timeout)
|
||||||
{
|
{
|
||||||
Result rc;
|
Result rc;
|
||||||
|
bool has_timeout = timeout != UINT64_MAX;
|
||||||
u64 deadline = 0;
|
u64 deadline = 0;
|
||||||
|
|
||||||
if (t->revent == INVALID_HANDLE)
|
if (t->revent == INVALID_HANDLE)
|
||||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||||
|
|
||||||
if (timeout != U64_MAX)
|
if (has_timeout)
|
||||||
deadline = armGetSystemTick() + armNsToTicks(timeout); // timeout: ns->ticks
|
deadline = armGetSystemTick() + armNsToTicks(timeout); // timeout: ns->ticks
|
||||||
|
|
||||||
do {
|
do {
|
||||||
do {
|
do {
|
||||||
s64 this_timeout = -1;
|
u64 this_timeout = UINT64_MAX;
|
||||||
if (deadline) {
|
if (has_timeout) {
|
||||||
this_timeout = deadline - armGetSystemTick();
|
s64 remaining = deadline - armGetSystemTick();
|
||||||
this_timeout = armTicksToNs(this_timeout >= 0 ? this_timeout : 0); // ticks->ns
|
this_timeout = remaining > 0 ? armTicksToNs(remaining) : 0; // ticks->ns
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = svcWaitSynchronizationSingle(t->revent, this_timeout);
|
rc = svcWaitSynchronizationSingle(t->revent, this_timeout);
|
||||||
if (deadline && (rc & 0x3FFFFF) == 0xEA01)
|
if (has_timeout && R_VALUE(rc) == KERNELRESULT(TimedOut))
|
||||||
return rc; // timeout.
|
return rc;
|
||||||
} while (R_FAILED(rc));
|
} while (R_VALUE(rc) == KERNELRESULT(Cancelled));
|
||||||
|
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
break;
|
||||||
|
|
||||||
if (t->autoclear)
|
if (t->autoclear)
|
||||||
rc = svcResetSignal(t->revent);
|
rc = svcResetSignal(t->revent);
|
||||||
} while ((rc & 0x3FFFFF) == 0xFA01);
|
} while (R_VALUE(rc) == KERNELRESULT(InvalidState));
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -145,39 +145,36 @@ clean_up:
|
|||||||
return rc;
|
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;
|
Result rc;
|
||||||
|
bool has_timeout = timeout != UINT64_MAX;
|
||||||
|
u64 deadline = 0;
|
||||||
|
|
||||||
|
if (has_timeout)
|
||||||
|
deadline = armGetSystemTick() + armNsToTicks(timeout); // timeout: ns->ticks
|
||||||
|
|
||||||
do {
|
do {
|
||||||
u64 cur_tick = armGetSystemTick();
|
u64 this_timeout = UINT64_MAX;
|
||||||
rc = wait(idx_out, objects, num_objects, timeout);
|
if (has_timeout) {
|
||||||
rc = R_VALUE(rc);
|
s64 remaining = deadline - armGetSystemTick();
|
||||||
|
this_timeout = remaining > 0 ? armTicksToNs(remaining) : 0; // ticks->ns
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} 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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result waitN(s32* idx_out, Waiter* objects, size_t num_objects, u64 timeout)
|
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)
|
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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user