hle: kernel: Refactor to allocate a ServiceThread per service handler.

- Previously, we would allocate a thread per session, which adds new threads on CloneCurrentObject.
- This results in race conditions with N sessions queuing requests to the same service interface.
- Fixes Pokken Tournament DX crashes/softlocks, which were regressed by #6347.
This commit is contained in:
bunnei
2021-06-04 19:26:48 -07:00
parent c8b3d92836
commit 27ce97fd42
13 changed files with 75 additions and 67 deletions

View File

@ -46,6 +46,7 @@ class KThread;
class KReadableEvent;
class KSession;
class KWritableEvent;
class ServiceThread;
enum class ThreadWakeupReason;
@ -56,7 +57,7 @@ enum class ThreadWakeupReason;
*/
class SessionRequestHandler : public std::enable_shared_from_this<SessionRequestHandler> {
public:
SessionRequestHandler();
SessionRequestHandler(KernelCore& kernel, const char* service_name_);
virtual ~SessionRequestHandler();
/**
@ -83,6 +84,14 @@ public:
* @param server_session ServerSession associated with the connection.
*/
void ClientDisconnected(KServerSession* session);
std::weak_ptr<ServiceThread> GetServiceThread() const {
return service_thread;
}
protected:
KernelCore& kernel;
std::weak_ptr<ServiceThread> service_thread;
};
using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;
@ -94,7 +103,8 @@ using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;
*/
class SessionRequestManager final {
public:
SessionRequestManager() = default;
explicit SessionRequestManager(KernelCore& kernel);
~SessionRequestManager();
bool IsDomain() const {
return is_domain;
@ -142,10 +152,18 @@ public:
session_handler = std::move(handler);
}
std::weak_ptr<ServiceThread> GetServiceThread() const {
return session_handler->GetServiceThread();
}
private:
bool is_domain{};
SessionRequestHandlerPtr session_handler;
std::vector<SessionRequestHandlerPtr> domain_handlers;
private:
KernelCore& kernel;
std::weak_ptr<ServiceThread> service_thread;
};
/**