// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include #include #include #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/k_light_lock.h" #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/result.h" namespace Core::Memory { class Memory; } namespace Core::Timing { class CoreTiming; struct EventType; } // namespace Core::Timing namespace Kernel { class HLERequestContext; class KernelCore; class KSession; class SessionRequestHandler; class SessionRequestManager; class KThread; class KServerSession final : public KSynchronizationObject, public boost::intrusive::list_base_hook<> { KERNEL_AUTOOBJECT_TRAITS(KServerSession, KSynchronizationObject); friend class ServiceThread; public: explicit KServerSession(KernelCore& kernel_); ~KServerSession() override; void Destroy() override; void Initialize(KSession* parent_session_, std::string&& name_, std::shared_ptr manager_); KSession* GetParent() { return parent; } const KSession* GetParent() const { return parent; } bool IsSignaled() const override; void OnClientClosed(); void ClientConnected(SessionRequestHandlerPtr handler) { if (manager) { manager->SetSessionHandler(std::move(handler)); } } void ClientDisconnected() { manager = nullptr; } /// Adds a new domain request handler to the collection of request handlers within /// this ServerSession instance. void AppendDomainHandler(SessionRequestHandlerPtr handler); /// Retrieves the total number of domain request handlers that have been /// appended to this ServerSession instance. std::size_t NumDomainRequestHandlers() const; /// Returns true if the session has been converted to a domain, otherwise False bool IsDomain() const { return manager && manager->IsDomain(); } /// Converts the session to a domain at the end of the current command void ConvertToDomain() { convert_to_domain = true; } /// Gets the session request manager, which forwards requests to the underlying service std::shared_ptr& GetSessionRequestManager() { return manager; } /// TODO: flesh these out to match the real kernel Result OnRequest(); Result SendReply(); Result ReceiveRequest(); private: /// Frees up waiting client sessions when this server session is about to die void CleanupRequests(); /// Queues a sync request from the emulated application. Result QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory); /// Completes a sync request from the emulated application. Result CompleteSyncRequest(HLERequestContext& context); /// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an /// object handle. Result HandleDomainSyncRequest(Kernel::HLERequestContext& context); /// This session's HLE request handlers; if nullptr, this is not an HLE server std::shared_ptr manager; /// When set to True, converts the session to a domain at the end of the command bool convert_to_domain{}; /// KSession that owns this KServerSession KSession* parent{}; /// List of threads which are pending a reply. /// FIXME: KSessionRequest std::list m_thread_request_list; KThread* m_current_thread_request{}; KLightLock m_lock; }; } // namespace Kernel