aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hle/service/am/event_observer.h
blob: 3e52e8494da79044eadd7768f37b704fdcdcda8d (plain)
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
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include "common/polyfill_thread.h"
#include "common/thread.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/os/event.h"
#include "core/hle/service/os/multi_wait.h"

namespace Core {
class System;
}

namespace Service::AM {

struct Applet;
class ProcessHolder;
class WindowSystem;

class EventObserver {
public:
    explicit EventObserver(Core::System& system, WindowSystem& window_system);
    ~EventObserver();

    void TrackAppletProcess(Applet& applet);
    void RequestUpdate();

private:
    void LinkDeferred();
    MultiWaitHolder* WaitSignaled();
    void Process(MultiWaitHolder* holder);
    bool WaitAndProcessImpl();
    void LoopProcess();

private:
    void OnWakeupEvent(MultiWaitHolder* holder);
    void OnProcessEvent(ProcessHolder* holder);

private:
    void DestroyAppletProcessHolderLocked(ProcessHolder* holder);

private:
    void ThreadFunc();

private:
    // System reference and context.
    Core::System& m_system;
    KernelHelpers::ServiceContext m_context;

    // Window manager.
    WindowSystem& m_window_system;

    // Guest event handle to wake up the event loop processor.
    Event m_wakeup_event;
    MultiWaitHolder m_wakeup_holder;

    // Mutex to protect remaining members.
    std::mutex m_lock{};

    // List of owned process holders.
    Common::IntrusiveListBaseTraits<ProcessHolder>::ListType m_process_holder_list;

    // Multi-wait objects for new tasks.
    MultiWait m_multi_wait;
    MultiWait m_deferred_wait_list;

    // Processing thread.
    std::thread m_thread{};
    std::stop_source m_stop_source{};
};

} // namespace Service::AM