From ad879ca327e74da134bc40a2b0c91d60d063e54f Mon Sep 17 00:00:00 2001 From: TuxSH Date: Tue, 13 Nov 2018 01:14:55 +0100 Subject: [PATCH] meso: Implement ConnectLight --- .../include/mesosphere/core/KAutoObject.hpp | 3 +++ mesosphere/include/mesosphere/core/Result.hpp | 2 ++ .../include/mesosphere/core/make_object.hpp | 9 +++++++ .../mesosphere/processes/KClientPort.hpp | 11 +++++--- .../processes/KLightClientSession.hpp | 2 +- .../mesosphere/processes/KLightSession.hpp | 4 ++- .../include/mesosphere/processes/KPort.hpp | 8 +++--- .../mesosphere/processes/KServerPort.hpp | 4 +-- mesosphere/source/processes/KClientPort.cpp | 26 ++++++++++++++++++- mesosphere/source/processes/KLightSession.cpp | 15 +++++++++-- mesosphere/source/processes/KPort.cpp | 4 +-- mesosphere/source/processes/KServerPort.cpp | 3 ++- 12 files changed, 73 insertions(+), 18 deletions(-) diff --git a/mesosphere/include/mesosphere/core/KAutoObject.hpp b/mesosphere/include/mesosphere/core/KAutoObject.hpp index 1b8d62d5b..983167460 100644 --- a/mesosphere/include/mesosphere/core/KAutoObject.hpp +++ b/mesosphere/include/mesosphere/core/KAutoObject.hpp @@ -35,6 +35,9 @@ MESOSPHERE_AUTO_OBJECT_FW_DECL(InterruptEvent); MESOSPHERE_AUTO_OBJECT_FW_DECL(LightSession); MESOSPHERE_AUTO_OBJECT_FW_DECL(LightClientSession); MESOSPHERE_AUTO_OBJECT_FW_DECL(LightServerSession); +MESOSPHERE_AUTO_OBJECT_FW_DECL(Port); +MESOSPHERE_AUTO_OBJECT_FW_DECL(ClientPort); +MESOSPHERE_AUTO_OBJECT_FW_DECL(ServerPort); class KAutoObject { public: diff --git a/mesosphere/include/mesosphere/core/Result.hpp b/mesosphere/include/mesosphere/core/Result.hpp index 9e5e688d2..c8bba95f5 100644 --- a/mesosphere/include/mesosphere/core/Result.hpp +++ b/mesosphere/include/mesosphere/core/Result.hpp @@ -97,6 +97,8 @@ class ResultError : public ResultBase> { #define DEFINE_RESULT(module, name, description) class Result##module##name final : public ResultError {} +DEFINE_RESULT(Kernel, OutOfSessions, 7); + DEFINE_RESULT(Kernel, InvalidCapabilityDescriptor, 14); DEFINE_RESULT(Kernel, NotImplemented, 33); diff --git a/mesosphere/include/mesosphere/core/make_object.hpp b/mesosphere/include/mesosphere/core/make_object.hpp index 9785a2cfc..caaad5f94 100644 --- a/mesosphere/include/mesosphere/core/make_object.hpp +++ b/mesosphere/include/mesosphere/core/make_object.hpp @@ -40,6 +40,15 @@ auto MakeObjectRaw(Args&& ...args) if constexpr (std::is_base_of_v, T>) { obj->AddToAllocatedSet(); } + } else { + if constexpr (std::is_base_of_v) { + delete &obj->GetClient(); + delete &obj->GetServer(); + } else { + delete obj; + } + + obj = nullptr; } cleanup: if (doReslimitCleanup) { diff --git a/mesosphere/include/mesosphere/processes/KClientPort.hpp b/mesosphere/include/mesosphere/processes/KClientPort.hpp index e278d310d..95dbe4138 100644 --- a/mesosphere/include/mesosphere/processes/KClientPort.hpp +++ b/mesosphere/include/mesosphere/processes/KClientPort.hpp @@ -1,10 +1,9 @@ #pragma once #include -#include -#include #include #include +#include namespace mesosphere { @@ -24,12 +23,16 @@ class KClientPort final : virtual bool IsSignaled() const override; + std::tuple> ConnectLight(); + private: friend class KPort; - std::atomic numSessions{0}, currentCapacity{0}, maxSessions{0}; + std::atomic numSessions{0}; + std::atomic peakNumNormalSessions{0}; + int maxSessions = 0; }; MESOSPHERE_AUTO_OBJECT_DEFINE_INCREF(ClientPort); -} \ No newline at end of file +} diff --git a/mesosphere/include/mesosphere/processes/KLightClientSession.hpp b/mesosphere/include/mesosphere/processes/KLightClientSession.hpp index cac4b620a..439ce42db 100644 --- a/mesosphere/include/mesosphere/processes/KLightClientSession.hpp +++ b/mesosphere/include/mesosphere/processes/KLightClientSession.hpp @@ -24,7 +24,7 @@ class KLightClientSession final : public KAutoObject, public IClient parentClientPort = nullptr; }; MESOSPHERE_AUTO_OBJECT_DEFINE_INCREF(LightClientSession); diff --git a/mesosphere/include/mesosphere/processes/KLightSession.hpp b/mesosphere/include/mesosphere/processes/KLightSession.hpp index 9e68530f6..a45003e4c 100644 --- a/mesosphere/include/mesosphere/processes/KLightSession.hpp +++ b/mesosphere/include/mesosphere/processes/KLightSession.hpp @@ -11,6 +11,8 @@ namespace mesosphere { +class KPort; + struct LightSessionRequest { s32 cmdId; u32 data[6]; @@ -28,7 +30,7 @@ class KLightSession final : virtual ~KLightSession(); - Result Initialize(); + Result Initialize(KPort *parentPort = nullptr); private: friend class KLightClientSession; diff --git a/mesosphere/include/mesosphere/processes/KPort.hpp b/mesosphere/include/mesosphere/processes/KPort.hpp index 3ca294c6f..8360c323c 100644 --- a/mesosphere/include/mesosphere/processes/KPort.hpp +++ b/mesosphere/include/mesosphere/processes/KPort.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include namespace mesosphere { @@ -23,12 +23,12 @@ class KPort final : Result Initialize(int maxSessions, bool isLight); + Result AddLightServerSession(KLightServerSession &lightServerSession); + private: friend class KClientPort; friend class KServerPort; - Result AddServerSession(KLightServerSession &lightServerSession); - bool isClientAlive = false; bool isServerAlive = false; bool isLight = false; @@ -36,4 +36,4 @@ class KPort final : MESOSPHERE_AUTO_OBJECT_DEFINE_INCREF(Port); -} \ No newline at end of file +} diff --git a/mesosphere/include/mesosphere/processes/KServerPort.hpp b/mesosphere/include/mesosphere/processes/KServerPort.hpp index 7b55dd5ab..8a85892ac 100644 --- a/mesosphere/include/mesosphere/processes/KServerPort.hpp +++ b/mesosphere/include/mesosphere/processes/KServerPort.hpp @@ -23,11 +23,11 @@ class KServerPort final : private: friend class KPort; - Result AddServerSession(KLightServerSession &lightServerSession); + Result AddLightServerSession(KLightServerSession &lightServerSession); KLightServerSession::List lightServerSessions{}; }; MESOSPHERE_AUTO_OBJECT_DEFINE_INCREF(ServerPort); -} \ No newline at end of file +} diff --git a/mesosphere/source/processes/KClientPort.cpp b/mesosphere/source/processes/KClientPort.cpp index b478e5a07..2bd304fdd 100644 --- a/mesosphere/source/processes/KClientPort.cpp +++ b/mesosphere/source/processes/KClientPort.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace mesosphere { @@ -14,7 +15,30 @@ KClientPort::~KClientPort() bool KClientPort::IsSignaled() const { - return false; // TODO + 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}; + } } } diff --git a/mesosphere/source/processes/KLightSession.cpp b/mesosphere/source/processes/KLightSession.cpp index 12858c867..d5222a386 100644 --- a/mesosphere/source/processes/KLightSession.cpp +++ b/mesosphere/source/processes/KLightSession.cpp @@ -1,4 +1,5 @@ #include +#include #include namespace mesosphere @@ -8,14 +9,24 @@ KLightSession::~KLightSession() { } -Result KLightSession::Initialize() +Result KLightSession::Initialize(KPort *parentPort) { SetClientServerParent(); isClientAlive = true; isServerAlive = true; SetResourceOwner(KCoreContext::GetCurrentInstance().GetCurrentProcess()); - return ResultSuccess(); + + if (parentPort == nullptr) { + return ResultSuccess(); + } else { + // Another difference with official kernel: if adding the session fails, the session isn't added to allocator set (since it'll be deleted right away). + Result res = parentPort->AddLightServerSession(server); + if (res.IsSuccess()) { + client.parentClientPort = &parentPort->GetClient(); + } + return res; + } } void KLightSession::Terminate(bool fromServer) diff --git a/mesosphere/source/processes/KPort.cpp b/mesosphere/source/processes/KPort.cpp index f9d1b9833..0edd27f81 100644 --- a/mesosphere/source/processes/KPort.cpp +++ b/mesosphere/source/processes/KPort.cpp @@ -21,13 +21,13 @@ Result KPort::Initialize(int maxSessions, bool isLight) return ResultSuccess(); } -Result KPort::AddServerSession(KLightServerSession &lightServerSession) +Result KPort::AddLightServerSession(KLightServerSession &lightServerSession) { KScopedCriticalSection critsec{}; if (isClientAlive || isServerAlive) { return ResultKernelConnectionRefused(); } else { - return server.AddServerSession(lightServerSession); + return server.AddLightServerSession(lightServerSession); } } diff --git a/mesosphere/source/processes/KServerPort.cpp b/mesosphere/source/processes/KServerPort.cpp index d91846c92..518ffeb8c 100644 --- a/mesosphere/source/processes/KServerPort.cpp +++ b/mesosphere/source/processes/KServerPort.cpp @@ -10,6 +10,7 @@ KServerPort::~KServerPort() { KScopedCriticalSection critsec{}; parent->isServerAlive = false; + // TODO } bool KServerPort::IsSignaled() const @@ -21,7 +22,7 @@ bool KServerPort::IsSignaled() const } } -Result KServerPort::AddServerSession(KLightServerSession &lightServerSession) +Result KServerPort::AddLightServerSession(KLightServerSession &lightServerSession) { KScopedCriticalSection critsec{}; bool wasEmpty = lightServerSessions.empty();