1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef UTILS_EVENT_REACTOR_H
17#define UTILS_EVENT_REACTOR_H
18
19#include <cstdint>
20#include <atomic>
21#include <memory>
22#include <mutex>
23#include <vector>
24#include <set>
25#include <queue>
26#include "io_event_common.h"
27#include "errors.h"
28#include "io_event_handler.h"
29
30namespace OHOS {
31namespace Utils {
32
33class IOEventEpoll;
34
35class IOEventReactor {
36public:
37    static constexpr uint8_t FLAG_CHANGED = 0x01;
38    static constexpr size_t INIT_FD_NUMS = 8;
39    static constexpr int EXPANSION_COEFF = 2;
40
41    IOEventReactor();
42    IOEventReactor(const IOEventReactor&) = delete;
43    IOEventReactor& operator=(const IOEventReactor&) = delete;
44    IOEventReactor(const IOEventReactor&&) = delete;
45    IOEventReactor& operator=(const IOEventReactor&&) = delete;
46    virtual ~IOEventReactor();
47
48    ErrCode SetUp();
49    ErrCode CleanUp();
50    ErrCode Clean(int fd);
51
52    ErrCode AddHandler(IOEventHandler* target);
53    ErrCode RemoveHandler(IOEventHandler* target);
54    ErrCode UpdateHandler(IOEventHandler* target);
55    ErrCode FindHandler(IOEventHandler* target);
56
57    void Run(int timeout);
58
59    inline void Terminate()
60    {
61        loopReady_ = false;
62    }
63
64    inline void EnableHandling()
65    {
66        enabled_ = true;
67    }
68
69    inline void DisableHandling()
70    {
71        enabled_ = false;
72    }
73private:
74    struct FdEvents {
75        std::shared_ptr<IOEventHandler> head;
76        EventId events;
77        uint8_t flags;
78
79        FdEvents()
80        {
81            head = std::make_shared<IOEventHandler>();
82            events = Events::EVENT_NONE;
83            flags = 0u;
84        }
85    };
86
87    bool HasHandler(IOEventHandler* target);
88    void InsertNodeFront(int fd, IOEventHandler* target);
89    void RemoveNode(IOEventHandler* target);
90
91    void HandleAll(const std::vector<std::pair<int, EventId>>&);
92    void Execute(const std::vector<EventCallback>& tasks);
93
94    ErrCode HandleEvents(int fd, EventId events);
95    bool UpdateToDemultiplexer(int fd);
96
97    bool DoClean(int fd);
98
99    std::mutex mutex_;
100    std::atomic<bool> loopReady_;
101    std::atomic<bool> enabled_;
102    std::atomic<uint32_t> count_;
103    std::vector<struct FdEvents> ioHandlers_;
104    std::unique_ptr<IOEventEpoll> backend_;
105};
106
107} // namespace Utils
108} // namespace OHOS
109#endif