Stratosphere: Implement support for deferred commands. Finish sm GetService()'s deferred path.

This commit is contained in:
Michael Scire
2018-04-22 03:02:08 -06:00
parent 809090e40d
commit 674528b246
16 changed files with 137 additions and 27 deletions

View File

@@ -16,6 +16,8 @@ enum IpcControlCommand {
};
#define POINTER_BUFFER_SIZE_MAX 0xFFFF
#define RESULT_DEFER_SESSION (0x6580A)
template <typename T>
class IServer;
@@ -68,6 +70,20 @@ class ServiceSession : public IWaitable {
return this->server_handle;
}
virtual void handle_deferred() {
Result rc = this->service_object->handle_deferred();
int handle_index;
if (rc != RESULT_DEFER_SESSION) {
this->set_deferred(false);
if (rc == 0xF601) {
svcCloseHandle(this->get_handle());
} else {
rc = svcReplyAndReceive(&handle_index, &this->server_handle, 0, this->server_handle, 0);
}
}
}
virtual Result handle_signaled(u64 timeout) {
Result rc;
int handle_index;
@@ -124,10 +140,15 @@ class ServiceSession : public IWaitable {
}
if (retval != 0xF601) {
rc = svcReplyAndReceive(&handle_index, &this->server_handle, 1, this->server_handle, 0);
} else {
if (retval == RESULT_DEFER_SESSION) {
/* Session defer. */
this->set_deferred(true);
rc = retval;
} else if (retval == 0xF601) {
/* Session close. */
rc = retval;
} else {
rc = svcReplyAndReceive(&handle_index, &this->server_handle, 0, this->server_handle, 0);
}
}