• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #ifndef HIVIEW_BASE_EVENT_LOOP_H
16 #define HIVIEW_BASE_EVENT_LOOP_H
17 #include <algorithm>
18 #include <atomic>
19 #include <future>
20 #include <map>
21 #include <memory>
22 #include <utility>
23 
24 #include <sys/types.h>
25 
26 #include "defines.h"
27 #include "event.h"
28 #include "event_priority_queue.h"
29 
30 #if defined(__HIVIEW_OHOS__)
31 #include "unique_fd.h"
32 #ifdef USE_POLL
33 #include <poll.h>
34 #endif
35 #elif defined(_WIN32)
36 #include <Windows.h>
37 #include <winnt.h>
38 #endif
39 
40 namespace OHOS {
41 namespace HiviewDFX {
42 constexpr int LOOP_WAKEUP_HANDLE_INDEX = 0;
43 constexpr int MAX_EVENT_SIZE = 16;
44 constexpr int MAX_HANDLE_ARRAY_SIZE = 1;
45 constexpr int MAX_WATCHED_FDS = 64;
46 constexpr uint64_t SECOND_TO_MICROSECOND = 1000000;
47 constexpr uint64_t SECOND_TO_NANOSECOND = 1000000000;
48 constexpr uint64_t NANOSECOND_TO_MILLSECOND = 1000000;
49 constexpr uint64_t MICROSECOND_TO_MILLSECOND = 1000;
50 constexpr uint64_t MICROSECOND_TO_NANOSECOND = 1000;
51 enum LoopEventType {
52     LOOP_EVENT_TASK,
53     LOOP_PACKAGED_TASK,
54 };
55 struct LoopEvent {
56     bool isRepeat = false;
57     uint8_t taskType = 0;
58     uint64_t seq = 0;
59     uint64_t interval = 0;
60     uint64_t enqueueTime = 0;
61     uint64_t targetTime = 0;
62     std::shared_ptr<Event> event = nullptr;
63     std::shared_ptr<EventHandler> handler = nullptr;
64     Task task = nullptr;
65     std::shared_ptr<std::packaged_task<bool()>> packagedTask = nullptr;
66 
CreateLoopEventLoopEvent67     static LoopEvent CreateLoopEvent(uint64_t now)
68     {
69         LoopEvent event;
70         event.isRepeat = false;
71         event.taskType = LOOP_EVENT_TASK;
72         event.seq = now;
73         event.interval = 0;
74         event.enqueueTime = now;
75         event.targetTime = now;
76         event.event = nullptr;
77         event.handler = nullptr;
78         event.task = nullptr;
79         event.packagedTask = nullptr;
80         return event;
81     }
82 
83     bool operator<(const LoopEvent &obj) const
84     {
85         // as we use std::priority_queue, the event with smaller target time will be in the top of the queue
86         return (this->targetTime > obj.targetTime);
87     }
88 };
89 
90 class FileDescriptorEventCallback {
91 public:
~FileDescriptorEventCallback()92     virtual ~FileDescriptorEventCallback(){};
93 #if defined(__HIVIEW_OHOS__)
94     virtual bool OnFileDescriptorEvent(int fd, int Type) = 0;
95     virtual int32_t GetPollFd() = 0;
96     virtual int32_t GetPollType() = 0;
97 #elif defined(_WIN32)
98     virtual bool OnHandleEvent(std::string fileName, DWORD action) = 0;
99 #endif
100 };
101 class DllExport EventLoop {
102 public:
103     explicit EventLoop(const std::string &name);
104     virtual ~EventLoop();
105     void StartLoop(bool createNewThread = true);
106     void StopLoop();
107 
108     // poll event from file descriptor source
109     // the interfaces may change on windows platform
110     bool AddFileDescriptorEventCallback(const std::string &name, std::shared_ptr<FileDescriptorEventCallback> source);
111     bool RemoveFileDescriptorEventCallback(const std::string &name);
112 
113     // process event immediately
114     uint64_t AddEvent(std::shared_ptr<EventHandler> handler, std::shared_ptr<Event> event, const Task task = nullptr);
115     std::future<bool> AddEventForResult(std::shared_ptr<EventHandler> handler, std::shared_ptr<Event> event);
116 
117     // process delayed event
118     // interval in seconds
119     uint64_t AddTimerEvent(std::shared_ptr<EventHandler> handler, std::shared_ptr<Event> event, const Task &task,
120         uint64_t interval, bool repeat);
121     bool RemoveEvent(uint64_t seq);
122 
GetName()123     const std::string &GetName() const
124     {
125         return name_;
126     };
127 
IsRunning()128     bool IsRunning() const
129     {
130         return isRunning_;
131     };
132 
133 private:
134     // call from audit module
GetHandlerInfo(const LoopEvent &)135     std::string GetHandlerInfo(const LoopEvent &)
136     {
137         return "";
138     };
139 
140     bool InitEventQueueNotifier();
141     void Run();
142     void WakeUp();
143     uint64_t ProcessQueuedEvent();
144     void WaitNextEvent(uint64_t leftTimeMill);
145     bool FetchNextEvent(uint64_t now, uint64_t& leftTimeNanosecond, LoopEvent& event);
146     void ProcessEvent(LoopEvent &event);
147     void ReInsertPeriodicEvent(uint64_t now, LoopEvent &event);
148     void ResetTimerIfNeedLocked();
149     uint64_t NanoSecondSinceSystemStart();
150     volatile bool isWaken_ = false;
151     volatile bool needQuit_ = false;
152     volatile bool isRunning_ = false;
153     std::string name_;
154     EventPriorityQueue<LoopEvent> pendingEvents_;
155     std::unique_ptr<std::thread> thread_;
156     std::mutex queueMutex_;
157 #if defined(__HIVIEW_OHOS__)
158 #ifdef USE_POLL
159     void ModifyFdStatus();
160     void PollNextEvent(uint64_t timeout);
161     volatile bool modifyFdStatus_ = false;
162     int32_t eventQueueFd_[2] = {-1, -1}; // 2:event queue fd size
163     int32_t watchedFdSize_ = 1;
164     struct pollfd watchFds_[MAX_WATCHED_FDS];
165 #else
166     UniqueFd pendingEventQueueFd_;
167     UniqueFd sharedPollingFd_;
168 #endif
169     std::map<int32_t, std::shared_ptr<FileDescriptorEventCallback>> eventSourceMap_;
170     std::map<std::string, int32_t> eventSourceNameMap_;
171 #elif defined(_WIN32)
172     HANDLE watchHandleList_[MAX_HANDLE_ARRAY_SIZE] = {NULL};
173 #endif
174     uint64_t nextWakeupTime_;
175     std::atomic<LoopEvent *> currentProcessingEvent_;
176 };
177 }  // namespace HiviewDFX
178 }  // namespace OHOS
179 #endif  // HIVIEW_BASE_EVENT_LOOP_H