#include #include #include #include #include namespace mesosphere { KClientPort::~KClientPort() { KScopedCriticalSection critsec{}; parent->isClientAlive = false; } bool KClientPort::IsSignaled() const { return numSessions.load() < maxSessions; } std::tuple> KClientPort::ConnectLight() { using RetType = std::tuple>; // Official kernel first checks reslimit then session max count. We will do the opposite. int curCount = numSessions.load(); while (curCount < maxSessions || !numSessions.compare_exchange_weak(curCount, curCount + 1)); if (curCount >= maxSessions) { return RetType{ResultKernelOutOfSessions(), nullptr}; } auto [res, serverSession, clientSession] = MakeObject(parent.get()); if (res.IsSuccess()) { serverSession.detach(); // Lifetime is now managed my KServerPort session list return RetType{ResultSuccess(), clientSession}; } else { if (numSessions.fetch_sub(1) == maxSessions) { NotifyWaiters(); } return RetType{res, nullptr}; } } }