trantor
Non-blocking I/O cross-platform TCP network library, using C++14
Loading...
Searching...
No Matches
EventLoop.h
1// Copyright 2010, Shuo Chen. All rights reserved.
2// http://code.google.com/p/muduo/
3//
4// Use of this source code is governed by a BSD-style license
5// that can be found in the License file.
6
7// Author: Shuo Chen (chenshuo at chenshuo dot com)
8
9// Taken from Muduo and modified
10// Copyright 2016, Tao An. All rights reserved.
11// https://github.com/an-tao/trantor
12//
13// Use of this source code is governed by a BSD-style license
14// that can be found in the License file.
15
16// Author: Tao An
17
18#pragma once
20#include <trantor/utils/Date.h>
22#include <trantor/exports.h>
23#include <thread>
24#include <memory>
25#include <vector>
26#include <mutex>
27#include <queue>
28#include <functional>
29#include <chrono>
30#include <limits>
31#include <atomic>
32
33namespace trantor
34{
35class Poller;
36class TimerQueue;
37class Channel;
38using ChannelList = std::vector<Channel *>;
39using Func = std::function<void()>;
40using TimerId = uint64_t;
41enum
42{
43 InvalidTimerId = 0
44};
45
55class TRANTOR_EXPORT EventLoop : NonCopyable
56{
57 public:
58 EventLoop();
59 ~EventLoop();
60
66 void loop();
67
72 void quit();
73
79 {
80 if (!isInLoopThread())
81 {
82 abortNotInLoopThread();
83 }
84 };
85#ifdef __linux__
90 void resetTimerQueue();
91#endif
97
105 bool isInLoopThread() const
106 {
107 return threadId_ == std::this_thread::get_id();
108 };
109
116 static EventLoop *getEventLoopOfCurrentThread();
117
125 template <typename Functor>
126 inline void runInLoop(Functor &&f)
127 {
128 if (isInLoopThread())
129 {
130 f();
131 }
132 else
133 {
134 queueInLoop(std::forward<Functor>(f));
135 }
136 }
137
146 void queueInLoop(const Func &f);
147 void queueInLoop(Func &&f);
148
156 TimerId runAt(const Date &time, const Func &cb);
157 TimerId runAt(const Date &time, Func &&cb);
158
166 TimerId runAfter(double delay, const Func &cb);
167 TimerId runAfter(double delay, Func &&cb);
168
178 TimerId runAfter(const std::chrono::duration<double> &delay, const Func &cb)
179 {
180 return runAfter(delay.count(), cb);
181 }
182 TimerId runAfter(const std::chrono::duration<double> &delay, Func &&cb)
183 {
184 return runAfter(delay.count(), std::move(cb));
185 }
186
194 TimerId runEvery(double interval, const Func &cb);
195 TimerId runEvery(double interval, Func &&cb);
196
207 TimerId runEvery(const std::chrono::duration<double> &interval,
208 const Func &cb)
209 {
210 return runEvery(interval.count(), cb);
211 }
212 TimerId runEvery(const std::chrono::duration<double> &interval, Func &&cb)
213 {
214 return runEvery(interval.count(), std::move(cb));
215 }
216
222 void invalidateTimer(TimerId id);
223
230
237
245
251 size_t index()
252 {
253 return index_;
254 }
255
261 void setIndex(size_t index)
262 {
263 index_ = index;
264 }
265
273 {
274 return looping_.load(std::memory_order_acquire) &&
275 (!quit_.load(std::memory_order_acquire));
276 }
277
285 {
286 return callingFuncs_;
287 }
288
295 void runOnQuit(Func &&cb);
296 void runOnQuit(const Func &cb);
297
298 private:
299 void abortNotInLoopThread();
300 void wakeup();
301 void wakeupRead();
302 std::atomic<bool> looping_;
303 std::thread::id threadId_;
304 std::atomic<bool> quit_;
305 std::unique_ptr<Poller> poller_;
306
307 ChannelList activeChannels_;
308 Channel *currentActiveChannel_;
309
310 bool eventHandling_;
311 MpscQueue<Func> funcs_;
312 std::unique_ptr<TimerQueue> timerQueue_;
313 MpscQueue<Func> funcsOnQuit_;
314 bool callingFuncs_{false};
315#ifdef __linux__
316 int wakeupFd_;
317 std::unique_ptr<Channel> wakeupChannelPtr_;
318#elif defined _WIN32
319#else
320 int wakeupFd_[2];
321 std::unique_ptr<Channel> wakeupChannelPtr_;
322#endif
323
324 void doRunInLoopFuncs();
325#ifdef _WIN32
326 size_t index_{size_t(-1)};
327#else
328 size_t index_{std::numeric_limits<size_t>::max()};
329#endif
330 EventLoop **threadLocalLoopPtr_;
331};
332
333} // namespace trantor
This class is used to implement reactor pattern. A Channel object manages a socket fd....
Definition Channel.h:33
This class represents a time point.
Definition Date.h:28
void loop()
Run the event loop. This method will be blocked until the event loop exits.
void resetAfterFork()
Make the event loop works after calling the fork() function.
void moveToCurrentThread()
Move the EventLoop to the current thread, this method must be called before the loop is running.
void setIndex(size_t index)
Set the index of the event loop.
Definition EventLoop.h:261
TimerId runAfter(double delay, const Func &cb)
Run a function after a period of time.
void quit()
Let the event loop quit.
TimerId runEvery(const std::chrono::duration< double > &interval, const Func &cb)
Repeatedly run a function every period of time. Users could use chrono literals to represent a time d...
Definition EventLoop.h:207
void invalidateTimer(TimerId id)
Invalidate the timer identified by the given ID.
static EventLoop * getEventLoopOfCurrentThread()
Get the event loop of the current thread. Return nullptr if there is no event loop in the current thr...
bool isRunning()
Return true if the event loop is running.
Definition EventLoop.h:272
void runInLoop(Functor &&f)
Run the function f in the thread of the event loop.
Definition EventLoop.h:126
TimerId runAfter(const std::chrono::duration< double > &delay, const Func &cb)
Run a function after a period of time.
Definition EventLoop.h:178
TimerId runAt(const Date &time, const Func &cb)
Run a function at a time point.
bool isInLoopThread() const
Return true if the current thread is the thread to which the event loop belongs.
Definition EventLoop.h:105
size_t index()
Return the index of the event loop.
Definition EventLoop.h:251
void queueInLoop(const Func &f)
Run the function f in the thread of the event loop.
bool isCallingFunctions()
Check if the event loop is calling a function.
Definition EventLoop.h:284
void updateChannel(Channel *chl)
Update channel status. This method is usually used internally.
void runOnQuit(Func &&cb)
Run functions when the event loop quits.
void removeChannel(Channel *chl)
Remove a channel from the event loop. This method is usually used internally.
TimerId runEvery(double interval, const Func &cb)
Repeatedly run a function every period of time.
void assertInLoopThread()
Assertion that the current thread is the thread to which the event loop belongs. If the assertion fai...
Definition EventLoop.h:78
This class template represents a lock-free multiple producers single consumer queue.
Definition LockFreeQueue.h:31
Definition EventLoop.h:34