os: implement 11.x SdkReplyAndReceive
This commit is contained in:
@@ -20,23 +20,32 @@
|
||||
|
||||
namespace ams::os::impl {
|
||||
|
||||
WaitableHolderBase *WaitableManagerImpl::WaitAnyImpl(bool infinite, TimeSpan timeout) {
|
||||
Result WaitableManagerImpl::WaitAnyImpl(WaitableHolderBase **out, bool infinite, TimeSpan timeout, bool reply, Handle reply_target) {
|
||||
/* Prepare for processing. */
|
||||
this->signaled_holder = nullptr;
|
||||
this->target_impl.SetCurrentThreadHandleForCancelWait();
|
||||
WaitableHolderBase *result = this->LinkHoldersToObjectList();
|
||||
WaitableHolderBase *holder = this->LinkHoldersToObjectList();
|
||||
|
||||
/* Check if we've been signaled. */
|
||||
{
|
||||
std::scoped_lock lk(this->cs_wait);
|
||||
if (this->signaled_holder != nullptr) {
|
||||
result = this->signaled_holder;
|
||||
holder = this->signaled_holder;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process object array. */
|
||||
if (result == nullptr) {
|
||||
result = this->WaitAnyHandleImpl(infinite, timeout);
|
||||
Result wait_result = ResultSuccess();
|
||||
if (holder != nullptr) {
|
||||
if (reply && reply_target != svc::InvalidHandle) {
|
||||
s32 index;
|
||||
wait_result = this->target_impl.TimedReplyAndReceive(std::addressof(index), nullptr, 0, 0, reply_target, TimeSpan::FromNanoSeconds(0));
|
||||
if (R_FAILED(wait_result)) {
|
||||
holder = nullptr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wait_result = this->WaitAnyHandleImpl(std::addressof(holder), infinite, timeout, reply, reply_target);
|
||||
}
|
||||
|
||||
/* Unlink holders from the current object list. */
|
||||
@@ -44,10 +53,13 @@ namespace ams::os::impl {
|
||||
|
||||
this->target_impl.ClearCurrentThreadHandleForCancelWait();
|
||||
|
||||
return result;
|
||||
/* Set output holder. */
|
||||
*out = holder;
|
||||
|
||||
return wait_result;
|
||||
}
|
||||
|
||||
WaitableHolderBase *WaitableManagerImpl::WaitAnyHandleImpl(bool infinite, TimeSpan timeout) {
|
||||
Result WaitableManagerImpl::WaitAnyHandleImpl(WaitableHolderBase **out, bool infinite, TimeSpan timeout, bool reply, Handle reply_target) {
|
||||
Handle object_handles[MaximumHandleCount];
|
||||
WaitableHolderBase *objects[MaximumHandleCount];
|
||||
|
||||
@@ -60,18 +72,30 @@ namespace ams::os::impl {
|
||||
TimeSpan min_timeout = 0;
|
||||
WaitableHolderBase *min_timeout_object = this->RecalculateNextTimeout(&min_timeout, end_time);
|
||||
|
||||
s32 index;
|
||||
if (infinite && min_timeout_object == nullptr) {
|
||||
index = this->target_impl.WaitAny(object_handles, MaximumHandleCount, count);
|
||||
s32 index = WaitInvalid;
|
||||
Result wait_result = ResultSuccess();
|
||||
if (reply) {
|
||||
if (infinite && min_timeout_object == nullptr) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
} else if (infinite && min_timeout_object == nullptr) {
|
||||
wait_result = this->target_impl.WaitAny(std::addressof(index), object_handles, MaximumHandleCount, count);
|
||||
} else {
|
||||
if (count == 0 && min_timeout == 0) {
|
||||
index = WaitTimedOut;
|
||||
} else {
|
||||
index = this->target_impl.TimedWaitAny(object_handles, MaximumHandleCount, count, min_timeout);
|
||||
wait_result = this->target_impl.TimedWaitAny(std::addressof(index), object_handles, MaximumHandleCount, count, min_timeout);
|
||||
AMS_ABORT_UNLESS(index != WaitInvalid);
|
||||
}
|
||||
}
|
||||
|
||||
if (index == WaitInvalid) {
|
||||
*out = nullptr;
|
||||
return wait_result;
|
||||
}
|
||||
|
||||
switch (index) {
|
||||
case WaitTimedOut:
|
||||
if (min_timeout_object) {
|
||||
@@ -79,23 +103,35 @@ namespace ams::os::impl {
|
||||
if (min_timeout_object->IsSignaled() == TriBool::True) {
|
||||
std::scoped_lock lk(this->cs_wait);
|
||||
this->signaled_holder = min_timeout_object;
|
||||
return this->signaled_holder;
|
||||
*out = min_timeout_object;
|
||||
return wait_result;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
*out = nullptr;
|
||||
return wait_result;
|
||||
}
|
||||
return nullptr;
|
||||
break;
|
||||
case WaitCancelled:
|
||||
if (this->signaled_holder) {
|
||||
return this->signaled_holder;
|
||||
}
|
||||
continue;
|
||||
default: /* 0 - 0x3F, valid. */
|
||||
{
|
||||
std::scoped_lock lk(this->cs_wait);
|
||||
if (this->signaled_holder) {
|
||||
*out = this->signaled_holder;
|
||||
return wait_result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: /* 0 - 0x3F, valid. */
|
||||
{
|
||||
AMS_ASSERT(0 <= index && index < static_cast<s32>(MaximumHandleCount));
|
||||
|
||||
std::scoped_lock lk(this->cs_wait);
|
||||
this->signaled_holder = objects[index];
|
||||
return this->signaled_holder;
|
||||
*out = objects[index];
|
||||
return wait_result;
|
||||
}
|
||||
}
|
||||
|
||||
reply_target = svc::InvalidHandle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user