SpiecsEngine
 
Loading...
Searching...
No Matches
EventLoop.cpp
Go to the documentation of this file.
1/**
2* @file EventLoop.cpp.
3* @brief The EventLoop Class Implementation.
4* @author Spices & Muduo.
5*/
6
7#include "Pchheader.h"
8#include "EventLoop.h"
9#include "Channel.h"
10#include "Poller/Poller.h"
11
12namespace Spices {
13
14namespace Net {
15
16 /**
17 * @brief Poller timeout.
18 * Default is 10s.
19 */
20 constexpr uint32_t pollTimeoutMs = 10 * 1000;
21
23 : m_IsLooping(false)
24 , m_IsQuit(false)
26 {
28
29 m_ThreadId = GetCurrentThreadId();
30 m_Poller = Poller::DefaultPoller(this);
31 m_WakeupFd.Create();
32 if (address)
33 {
34 m_WakeupFd.Connect(address);
35 }
36 m_WeakupChannel = std::make_unique<Channel>(m_WakeupFd.Fd(), this);
37
38 m_WeakupChannel->SetReadCallback([=]() { HandleWakeUp(); });
39 m_WeakupChannel->EnableReading();
40 }
41
43 {
44 m_WeakupChannel->DisableAll();
45 m_WeakupChannel->Remove();
46 }
47
49 {
50 m_IsLooping = true;
51 m_IsQuit = false;
52
53 while (!m_IsQuit)
54 {
55 m_ActiveChannels.clear();
56 m_Poller->Poll(pollTimeoutMs, &m_ActiveChannels);
57
58 for (Channel* channel : m_ActiveChannels)
59 {
60 channel->HandleEvent();
61 }
62
63 DoPendingFunctors();
64 }
65
66 m_IsLooping = false;
67 }
68
70 {
71 m_IsQuit = true;
72
74 {
76 }
77 }
78
79 void EventLoop::RunInLoop(Functor cb)
80 {
82 {
83 cb();
84 }
85 else
86 {
87 QueueInLoop(cb);
88 }
89 }
90
91 void EventLoop::QueueInLoop(Functor cb)
92 {
93 {
94 std::unique_lock<std::mutex> lock(m_Mutex);
95 m_PendingFunctors.emplace_back(cb);
96 }
97
98 if (!IsInLoopThread() || m_IsCallingPendingFunctors)
99 {
100 WakeUp();
101 }
102 }
103
105 {
106 char one = 1;
107 int n = ::send(m_WakeupFd.Fd(), &one, sizeof(one), 0);
108 if (n < 0)
109 {
110 std::stringstream ss;
111 ss << "EventLoop::WakeUp error, Error: " << WSAGetLastError();
112
113 SPICES_CORE_ERROR(ss.str())
114 }
115 }
116
117 void EventLoop::UpdateChannel(Channel* channel) const
118 {
119 m_Poller->UpdateChannel(channel);
120 }
121
122 void EventLoop::RemoveChannel(Channel* channel) const
123 {
124 m_Poller->RemoveChannel(channel);
125 }
126
127 bool EventLoop::HasChannel(Channel* channel) const
128 {
129 return m_Poller->HasChannel(channel);
130 }
131
133 {
134 char one = 1;
135 int n = ::recv(m_WakeupFd.Fd(), &one, sizeof(one), 0);
136 if (n < 0)
137 {
138 std::stringstream ss;
139 ss << "EventLoop::HandleWakeUp error, Error: " << WSAGetLastError();
140
141 SPICES_CORE_ERROR(ss.str())
142 }
143 }
144
146 {
147 std::vector<Functor> functors;
148 m_IsCallingPendingFunctors = true;
149
150 {
151 std::unique_lock<std::mutex> lock(m_Mutex);
152 functors.swap(m_PendingFunctors);
153 }
154
155 for (const Functor& functor : functors)
156 {
157 functor();
158 }
159
160 m_IsCallingPendingFunctors = false;
161 }
162
164 {
166
167 if (instance)
168 {
169 delete instance;
170 }
171 }
172
174 {
176
177 /**
178 * @brief Thread Unique EventLoop.
179 */
180 static _declspec(thread) EventLoopThreadWrapper pTLSEventLoop;
181
182 if (!pTLSEventLoop.instance)
183 {
184 pTLSEventLoop.instance = new EventLoop(address);
185 }
186
187 return pTLSEventLoop.instance;
188 }
189
190}
191
192}
#define SPICES_PROFILE_ZONE
Wrapper of SOCKET'S Event.
Definition Channel.h:27
virtual ~EventLoopThreadWrapper()
Destructor Function.
static EventLoop *& GetInst(InetAddress *address=nullptr)
Get EventLoop Instance. @reutrn Returns EventLoop Instance.
EventLoop * instance
This thread EventLoop instance.
Definition EventLoop.h:204
Wrapper of Instance/Delete ThreadCache in thread.
Definition EventLoop.h:180
void HandleWakeUp()
Handle WakeUp notify by read one byte data.
void DoPendingFunctors()
Execute all pending functors.
bool HasChannel(Channel *channel) const
Determine if channel is inside poller.
EventLoop(InetAddress *address=nullptr)
Constructor Function.
Definition EventLoop.cpp:22
void WakeUp()
WakeUp a thread, which wait on recv, by sending one byte data.
void Loop()
Start Event Loop.
Definition EventLoop.cpp:48
bool IsInLoopThread() const
Determine if current thread is in eventloop thread.
Definition EventLoop.h:109
void RunInLoop(Functor cb)
Push functor to pending functors.
Definition EventLoop.cpp:79
~EventLoop()
Destructor Function.
Definition EventLoop.cpp:42
void QueueInLoop(Functor cb)
Execute functor in EventLoop thread.
Definition EventLoop.cpp:91
void UpdateChannel(Channel *channel) const
Update channel state with poller.
void Quit()
Quit from Event Loop.
Definition EventLoop.cpp:69
void RemoveChannel(Channel *channel) const
Remove channel from poller.
Wrapper of Poller and wakeup socket to acceptor(SubLoop).
Definition EventLoop.h:28
This class is Wrapper of current socket address.
Definition InetAddress.h:22
constexpr uint32_t pollTimeoutMs
Poller timeout. Default is 10s.
Definition EventLoop.cpp:20