tipc/sm: update more fully for 13.0.0 changes

This commit is contained in:
Michael Scire 2021-10-13 23:50:57 -07:00
parent ca25a884b5
commit 891fa32bf1
10 changed files with 357 additions and 309 deletions

View file

@ -40,99 +40,12 @@ namespace ams::sm {
static_assert(MaxSessionsTotal % NumTipcPorts == 0);
/* Define WaitList class. */
class WaitList {
public:
using Key = sm::ServiceName;
private:
struct Entry {
sm::ServiceName service_name{sm::InvalidServiceName};
tipc::ObjectHolder object{};
u8 message_buffer[svc::ipc::MessageBufferSize];
};
private:
Entry m_entries[MaxSessionsTotal / NumTipcPorts]{};
Entry *m_processing_entry{};
public:
constexpr WaitList() = default;
public:
Result StartRegisterRetry(sm::ServiceName service_name) {
/* Check that we're not already processing a retry. */
AMS_ABORT_UNLESS(m_processing_entry == nullptr);
/* Find a free entry. */
Entry *free_entry = nullptr;
for (auto &entry : m_entries) {
if (entry.service_name == InvalidServiceName) {
free_entry = std::addressof(entry);
break;
}
}
/* Verify that we found a free entry. */
R_UNLESS(free_entry != nullptr, sm::ResultOutOfProcesses());
/* Populate the entry. */
free_entry->service_name = service_name;
std::memcpy(free_entry->message_buffer, svc::ipc::GetMessageBuffer(), util::size(free_entry->message_buffer));
/* Set the processing entry. */
m_processing_entry = free_entry;
/* Return the special request deferral result. */
return tipc::ResultRequestDeferred();
}
void ProcessRegisterRetry(tipc::ObjectHolder &object) {
/* Verify that we have a processing entry. */
AMS_ABORT_UNLESS(m_processing_entry != nullptr);
/* Set the entry's object. */
m_processing_entry->object = object;
/* Clear our processing entry. */
m_processing_entry = nullptr;
}
bool TestResume(sm::ServiceName service_name) {
/* Check that we have a matching service name. */
for (const auto &entry : m_entries) {
if (entry.service_name == service_name) {
return true;
}
}
return false;
}
template<typename PortManagerType>
void Resume(sm::ServiceName service_name, PortManagerType *port_manager) {
/* Resume (and clear) all matching entries. */
for (auto &entry : m_entries) {
if (entry.service_name == service_name) {
/* Copy the saved message buffer. */
std::memcpy(svc::ipc::GetMessageBuffer(), entry.message_buffer, svc::ipc::MessageBufferSize);
/* Resume the request. */
R_TRY_CATCH(port_manager->ProcessRequest(entry.object)) {
R_CATCH(tipc::ResultRequestDeferred) {
this->ProcessRegisterRetry(entry.object);
}
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
/* Clear the entry's service name. */
entry.service_name = sm::InvalidServiceName;
}
}
}
};
/* Define port metadata. */
using UserPortMeta = tipc::PortMeta<MaxSessionsUser, impl::IUserInterface, UserService, tipc::SlabAllocator>;
using ManagerPortMeta = tipc::PortMeta<MaxSessionsManager, impl::IManagerInterface, ManagerService, tipc::SingletonAllocator>;
using UserPortMeta = tipc::PortMeta<MaxSessionsUser, impl::IUserInterface, UserService, tipc::SlabAllocator>;
using ManagerPortMeta = tipc::PortMeta<MaxSessionsManager, impl::IManagerInterface, ManagerService, tipc::SingletonAllocator>;
/* Define server manager global. */
using ServerManager = tipc::ServerManagerWithDeferral<sm::WaitList, ManagerPortMeta, UserPortMeta>;
using ServerManager = tipc::ServerManager<ManagerPortMeta, UserPortMeta>;
ServerManager g_server_manager;
@ -162,14 +75,6 @@ namespace ams::sm {
g_server_manager.LoopAuto();
}
Result StartRegisterRetry(sm::ServiceName service_name) {
/* Get the port manager from where it's saved in TLS. */
auto *port_manager = reinterpret_cast<typename ServerManager::PortManagerBase *>(os::GetTlsValue(g_server_manager.GetTlsSlot()));
/* Register the retry. */
return port_manager->StartRegisterRetry(service_name);
}
void TriggerResume(sm::ServiceName service_name) {
/* Trigger a resumption. */
g_server_manager.TriggerResume(service_name);