SpiecsEngine
 
Loading...
Searching...
No Matches
EPollPoller.cpp
Go to the documentation of this file.
1/**
2* @file EPollPoller.cpp.
3* @brief The EPollPoller Class Implementation.
4* @author Spices & Muduo.
5*/
6
7#include "Pchheader.h"
8#include "EPollPoller.h"
9#include "../Channel.h"
10
11namespace Spices {
12
13namespace Net {
14
15 static constexpr int InitEventListSize = 16;
16
18 : Poller(loop)
21 {}
22
24 {
25 epoll_close(m_EPollFd);
26 }
27
28 void EPollPoller::Poll(int timeoutMs, ChannelList* activeChannels)
29 {
30 const int numEvents = epoll_wait(m_EPollFd, m_Events.data(), m_Events.size(), timeoutMs);
31 const int saveErrno = WSAGetLastError();
32
33 if (numEvents > 0)
34 {
35 FillActiveChannels(numEvents, activeChannels);
36
37 if (numEvents == m_Events.size())
38 {
39 m_Events.resize(m_Events.size() * 2);
40 }
41 }
42 else if (numEvents == 0)
43 {
44 SPICES_CORE_INFO("EPollPoller::Poll timeout")
45 }
46 else
47 {
48 if (saveErrno != ERROR_OPERATION_ABORTED)
49 {
50 std::stringstream ss;
51 ss << "EPollPoller::Poll Error: " << saveErrno;
52
53 SPICES_CORE_ERROR(ss.str())
54 }
55 }
56 }
57
59 {
60 const auto state = channel->GetPollState();
61
63 {
64 if (state == Channel::PollState::New)
65 {
66 SOCKET fd = channel->Fd();
67 m_Channels[fd] = channel;
68 }
69
71 Update(EPOLL_CTL_ADD, channel);
72 }
73 else
74 {
75 SOCKET fd = channel->Fd();
76 if (channel->IsNoneEvent())
77 {
78 Update(EPOLL_CTL_DEL, channel);
80 }
81 else
82 {
83 Update(EPOLL_CTL_MOD, channel);
84 }
85 }
86 }
87
89 {
90 SOCKET fd = channel->Fd();
91 m_Channels.erase(fd);
92
93 const auto state = channel->GetPollState();
94 if (state == Channel::PollState::Added)
95 {
96 Update(EPOLL_CTL_DEL, channel);
97 }
99 }
100
101 void EPollPoller::FillActiveChannels(int numEvents, ChannelList* activeChannels) const
102 {
103 for (int i = 0; i < numEvents; ++i)
104 {
105 Channel* channel = static_cast<Channel*>(m_Events[i].data.ptr);
106 channel->SetRevents(m_Events[i].events);
107 activeChannels->push_back(channel);
108 }
109 }
110
111 void EPollPoller::Update(int operation, Channel* channel) const
112 {
113 epoll_event event = {};
114
115 SOCKET fd = channel->Fd();
116
117 event.events = channel->Events();
118 event.data.sock = fd;
119 event.data.ptr = channel;
120
121 if(::epoll_ctl(m_EPollFd, operation, fd, &event))
122 {
123 if(operation == EPOLL_CTL_DEL)
124 {
125 std::stringstream ss;
126 ss << "EPollPoller::Update::EPOLL_CTL_DEL Error: " << WSAGetLastError();
127
128 SPICES_CORE_ERROR(ss.str())
129 }
130 else
131 {
132 std::stringstream ss;
133 ss << "EPollPoller::Update::EPOLL_CTL_ADD/MOD Error: " << WSAGetLastError();
134
135 SPICES_CORE_CRITICAL(ss.str())
136 }
137 }
138 }
139
140}
141
142}
void SetPollState(PollState state)
Set Poll State.
Definition Channel.h:208
PollState GetPollState() const
Get Poll State.
Definition Channel.h:202
bool IsNoneEvent() const
Determine whether the event is a None Event.
Definition Channel.h:184
Wrapper of SOCKET'S Event.
Definition Channel.h:27
virtual ~EPollPoller() override
Destructor Function.
void Update(int operation, Channel *channel) const
Update epoll with operation.
virtual void Poll(int timeoutMs, ChannelList *activeChannels) override
Poll events on EventList.
virtual void UpdateChannel(Channel *channel) override
Update Channel and Update Poll.
virtual void RemoveChannel(Channel *channel) override
Remove Channel and Update Poll.
void FillActiveChannels(int numEvents, ChannelList *activeChannels) const
Fill REvents to ChannelList.
EPollPoller(EventLoop *loop)
Constructor Function.
Wrapper of Poller and wakeup socket to acceptor(SubLoop).
Definition EventLoop.h:28
Poller(EventLoop *loop)
Constructor Function.
Definition Poller.h:37
Inherit from this and Implement Specific Poller.
Definition Poller.h:25
static constexpr int InitEventListSize