ams_mitm: begin skeleton refactor

This commit is contained in:
Michael Scire 2019-11-20 23:58:18 -08:00
parent ba0edbd9c4
commit ef090419f7
7 changed files with 79 additions and 45 deletions

View File

@ -162,7 +162,3 @@ extern "C" {
void abort() {
ams::AbortImpl();
}
void *__cxa_allocate_ecxeption(size_t thrown_size) {
abort();
}

View File

@ -147,24 +147,32 @@ namespace ams::sf::hipc {
/* Iterate over the list of deferred sessions, and see if we can't do anything. */
std::scoped_lock lk(this->deferred_session_mutex);
auto it = this->deferred_session_list.begin();
while (it != this->deferred_session_list.end()) {
ServerSession *session = static_cast<ServerSession *>(&*it);
R_TRY_CATCH(this->ProcessForSession(session)) {
R_CATCH(sf::ResultRequestDeferred) {
/* Session is still deferred, so let's continue. */
it++;
continue;
}
R_CATCH(sf::impl::ResultRequestInvalidated) {
/* Session is no longer deferred! */
it = this->deferred_session_list.erase(it);
continue;
}
} R_END_TRY_CATCH_WITH_ASSERT;
/* Undeferring a request may undefer another request. We'll continue looping until everything is stable. */
bool needs_undefer_all = true;
while (needs_undefer_all) {
needs_undefer_all = false;
/* We succeeded! Remove from deferred list. */
it = this->deferred_session_list.erase(it);
auto it = this->deferred_session_list.begin();
while (it != this->deferred_session_list.end()) {
ServerSession *session = static_cast<ServerSession *>(&*it);
R_TRY_CATCH(this->ProcessForSession(session)) {
R_CATCH(sf::ResultRequestDeferred) {
/* Session is still deferred, so let's continue. */
it++;
continue;
}
R_CATCH(sf::impl::ResultRequestInvalidated) {
/* Session is no longer deferred! */
it = this->deferred_session_list.erase(it);
needs_undefer_all = true;
continue;
}
} R_END_TRY_CATCH_WITH_ASSERT;
/* We succeeded! Remove from deferred list. */
it = this->deferred_session_list.erase(it);
needs_undefer_all = true;
}
}
}

View File

@ -49,6 +49,18 @@ static Service g_smAtmosphereMitmSrv;
NX_GENERATE_SERVICE_GUARD(smAtmosphereMitm);
Result _smAtmosphereMitmInitialize(void) {
return smAtmosphereOpenSession(&g_smAtmosphereMitmSrv);
}
void _smAtmosphereMitmCleanup(void) {
smAtmosphereCloseSession(&g_smAtmosphereMitmSrv);
}
Service* smAtmosphereMitmGetServiceSession(void) {
return &g_smAtmosphereMitmSrv;
}
Result smAtmosphereOpenSession(Service *out) {
Handle sm_handle;
Result rc = svcConnectToNamedPort(&sm_handle, "sm:");
while (R_VALUE(rc) == KERNELRESULT(NotFound)) {
@ -57,28 +69,24 @@ Result _smAtmosphereMitmInitialize(void) {
}
if (R_SUCCEEDED(rc)) {
serviceCreate(&g_smAtmosphereMitmSrv, sm_handle);
serviceCreate(out, sm_handle);
}
if (R_SUCCEEDED(rc)) {
const u64 pid_placeholder = 0;
rc = serviceDispatchIn(&g_smAtmosphereMitmSrv, 0, pid_placeholder, .in_send_pid = true);
rc = serviceDispatchIn(out, 0, pid_placeholder, .in_send_pid = true);
}
return rc;
}
void _smAtmosphereMitmCleanup(void) {
serviceClose(&g_smAtmosphereMitmSrv);
void smAtmosphereCloseSession(Service *srv) {
serviceClose(srv);
}
Service* smAtmosphereMitmGetServiceSession(void) {
return &g_smAtmosphereMitmSrv;
}
Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, SmServiceName name) {
Result smAtmosphereMitmInstall(Service *fwd_srv, Handle *handle_out, Handle *query_out, SmServiceName name) {
Handle tmp_handles[2];
Result rc = serviceDispatchIn(&g_smAtmosphereMitmSrv, 65000, name,
Result rc = serviceDispatchIn(fwd_srv, 65000, name,
.out_handle_attrs = { SfOutHandleAttr_HipcMove, SfOutHandleAttr_HipcMove },
.out_handles = tmp_handles,
);
@ -92,11 +100,11 @@ Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, SmServiceN
}
Result smAtmosphereMitmUninstall(SmServiceName name) {
return _smAtmosphereCmdInServiceNameNoOut(name, &g_smAtmosphereMitmSrv, 65001);
return _smAtmosphereCmdInServiceNameNoOut(name, smGetServiceSession(), 65001);
}
Result smAtmosphereMitmDeclareFuture(SmServiceName name) {
return _smAtmosphereCmdInServiceNameNoOut(name, &g_smAtmosphereMitmSrv, 65006);
return _smAtmosphereCmdInServiceNameNoOut(name, smGetServiceSession(), 65006);
}
Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, u64 *tid_out, SmServiceName name) {

View File

@ -22,7 +22,10 @@ Result smAtmosphereMitmInitialize(void);
void smAtmosphereMitmExit(void);
Service *smAtmosphereMitmGetServiceSession();
Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, SmServiceName name);
Result smAtmosphereOpenSession(Service *out);
void smAtmosphereCloseSession(Service *srv);
Result smAtmosphereMitmInstall(Service *fwd_srv, Handle *handle_out, Handle *query_out, SmServiceName name);
Result smAtmosphereMitmUninstall(SmServiceName name);
Result smAtmosphereMitmDeclareFuture(SmServiceName name);
Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, u64 *tid_out, SmServiceName name);

View File

@ -19,25 +19,25 @@ namespace ams::sm::mitm {
/* Mitm API. */
Result InstallMitm(Handle *out_port, Handle *out_query, ServiceName name) {
return impl::DoWithMitmSession([&]() {
return smAtmosphereMitmInstall(out_port, out_query, impl::ConvertName(name));
return impl::DoWithPerThreadSession([&](Service *fwd) {
return smAtmosphereMitmInstall(fwd, out_port, out_query, impl::ConvertName(name));
});
}
Result UninstallMitm(ServiceName name) {
return impl::DoWithMitmSession([&]() {
return impl::DoWithUserSession([&]() {
return smAtmosphereMitmUninstall(impl::ConvertName(name));
});
}
Result DeclareFutureMitm(ServiceName name) {
return impl::DoWithMitmSession([&]() {
return impl::DoWithUserSession([&]() {
return smAtmosphereMitmDeclareFuture(impl::ConvertName(name));
});
}
Result AcknowledgeSession(Service *out_service, os::ProcessId *out_process_id, ncm::ProgramId *out_program_id, ServiceName name) {
return impl::DoWithMitmSession([&]() {
return impl::DoWithMitmAcknowledgementSession([&]() {
return smAtmosphereMitmAcknowledgeSession(out_service, &out_process_id->value, &out_program_id->value, impl::ConvertName(name));
});
}

View File

@ -21,7 +21,8 @@ namespace ams::sm::impl {
/* Globals. */
os::RecursiveMutex g_user_session_mutex;
os::RecursiveMutex g_mitm_session_mutex;
os::RecursiveMutex g_mitm_ack_session_mutex;
os::RecursiveMutex g_per_thread_session_mutex;
}
@ -30,8 +31,12 @@ namespace ams::sm::impl {
return g_user_session_mutex;
}
os::RecursiveMutex &GetMitmSessionMutex() {
return g_mitm_session_mutex;
os::RecursiveMutex &GetMitmAcknowledgementSessionMutex() {
return g_mitm_ack_session_mutex;
}
os::RecursiveMutex &GetPerThreadSessionMutex() {
return g_per_thread_session_mutex;
}
}

View File

@ -22,7 +22,8 @@ namespace ams::sm::impl {
/* Utilities. */
os::RecursiveMutex &GetUserSessionMutex();
os::RecursiveMutex &GetMitmSessionMutex();
os::RecursiveMutex &GetMitmAcknowledgementSessionMutex();
os::RecursiveMutex &GetPerThreadSessionMutex();
template<typename F>
Result DoWithUserSession(F f) {
@ -36,8 +37,8 @@ namespace ams::sm::impl {
}
template<typename F>
Result DoWithMitmSession(F f) {
std::scoped_lock<os::RecursiveMutex &> lk(GetMitmSessionMutex());
Result DoWithMitmAcknowledgementSession(F f) {
std::scoped_lock<os::RecursiveMutex &> lk(GetMitmAcknowledgementSessionMutex());
{
R_ASSERT(smAtmosphereMitmInitialize());
ON_SCOPE_EXIT { smAtmosphereMitmExit(); };
@ -46,6 +47,19 @@ namespace ams::sm::impl {
}
}
template<typename F>
Result DoWithPerThreadSession(F f) {
Service srv;
{
std::scoped_lock<os::RecursiveMutex &> lk(GetPerThreadSessionMutex());
R_ASSERT(smAtmosphereOpenSession(&srv));
}
{
ON_SCOPE_EXIT { smAtmosphereCloseSession(&srv); };
return f(&srv);
}
}
NX_CONSTEXPR SmServiceName ConvertName(sm::ServiceName name) {
static_assert(sizeof(SmServiceName) == sizeof(sm::ServiceName));
SmServiceName ret = {};