summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/k_server_session.h
blob: 27b757ad27d3c0b5528c0eb64a91eaeafee00951 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#pragma once

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <boost/intrusive/list.hpp>

#include "common/threadsafe_queue.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/kernel/service_thread.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 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_, std::string&& name_);

    KSession* GetParent() {
        return parent;
    }

    const KSession* GetParent() const {
        return parent;
    }

    bool IsSignaled() const override;

    void OnClientClosed();

    /**
     * Sets the HLE handler for the session. This handler will be called to service IPC requests
     * instead of the regular IPC machinery. (The regular IPC machinery is currently not
     * implemented.)
     */
    void SetSessionHandler(SessionRequestHandlerPtr handler) {
        manager->SetSessionHandler(std::move(handler));
    }

    /**
     * Handle a sync request from the emulated application.
     *
     * @param thread      Thread that initiated the request.
     * @param memory      Memory context to handle the sync request under.
     * @param core_timing Core timing context to schedule the request event under.
     *
     * @returns ResultCode from the operation.
     */
    ResultCode HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory,
                                 Core::Timing::CoreTiming& core_timing);

    /// 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->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<SessionRequestManager>& GetSessionRequestManager() {
        return manager;
    }

    /// Gets the session request manager, which forwards requests to the underlying service
    const std::shared_ptr<SessionRequestManager>& GetSessionRequestManager() const {
        return manager;
    }

    /// Sets the session request manager, which forwards requests to the underlying service
    void SetSessionRequestManager(std::shared_ptr<SessionRequestManager> manager_) {
        manager = std::move(manager_);
    }

private:
    /// Queues a sync request from the emulated application.
    ResultCode QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory);

    /// Completes a sync request from the emulated application.
    ResultCode CompleteSyncRequest(HLERequestContext& context);

    /// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an
    /// object handle.
    ResultCode HandleDomainSyncRequest(Kernel::HLERequestContext& context);

    /// This session's HLE request handlers
    std::shared_ptr<SessionRequestManager> manager;

    /// When set to True, converts the session to a domain at the end of the command
    bool convert_to_domain{};

    /// Thread to dispatch service requests
    std::weak_ptr<ServiceThread> service_thread;

    /// KSession that owns this KServerSession
    KSession* parent{};
};

} // namespace Kernel