-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPollDispatcher.cpp
128 lines (121 loc) · 2.67 KB
/
PollDispatcher.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "Dispatcher.h"
#include <poll.h>
#include <stdlib.h>
#include <stdio.h>
#include "PollDispatcher.h"
PollDispatcher::PollDispatcher(EventLoop* evloop) : Dispatcher(evloop)
{
m_maxfd = 0;
m_fds = new struct pollfd[m_maxNode];
for (int i = 0; i < m_maxNode; ++i)
{
m_fds[i].fd = -1;
m_fds[i].events = 0;
m_fds[i].revents = 0;
}
m_name = "Poll";
}
PollDispatcher::~PollDispatcher()
{
delete[]m_fds;
}
int PollDispatcher::add()
{
int events = 0;
if (m_channel->getEvent() & (int)FDEvent::ReadEvent)
{
events |= POLLIN;
}
if (m_channel->getEvent() & (int)FDEvent::WriteEvent)
{
events |= POLLOUT;
}
int i = 0;
for (; i < m_maxNode; ++i)
{
if (m_fds[i].fd == -1)
{
m_fds[i].events = events;
m_fds[i].fd = m_channel->getSocket();
m_maxfd = i > m_maxfd ? i : m_maxfd;
break;
}
}
if (i >= m_maxNode)
{
return -1;
}
return 0;
}
int PollDispatcher::remove()
{
int i = 0;
for (; i < m_maxNode; ++i)
{
if (m_fds[i].fd == m_channel->getSocket())
{
m_fds[i].events = 0;
m_fds[i].revents = 0;
m_fds[i].fd = -1;
break;
}
}
// 通过 channel 释放对应的 TcpConnection 资源
m_channel->destroyCallback(const_cast<void*>(m_channel->getArg()));
if (i >= m_maxNode)
{
return -1;
}
return 0;
}
int PollDispatcher::modify()
{
int events = 0;
if (m_channel->getEvent() & (int)FDEvent::ReadEvent)
{
events |= POLLIN;
}
if (m_channel->getEvent() & (int)FDEvent::WriteEvent)
{
events |= POLLOUT;
}
int i = 0;
for (; i < m_maxNode; ++i)
{
if (m_fds[i].fd == m_channel->getSocket())
{
m_fds[i].events = events;
break;
}
}
if (i >= m_maxNode)
{
return -1;
}
return 0;
}
int PollDispatcher::dispatch(int timeout)
{
int count = poll(m_fds, m_maxfd + 1, timeout * 1000);
if (count == -1)
{
perror("poll");
exit(0);
}
for (int i = 0; i <= m_maxfd; ++i)
{
if (m_fds[i].fd == -1)
{
continue;
}
if (m_fds[i].revents & POLLIN)
{
m_evLoop->eventActive(m_fds[i].fd, (int)FDEvent::ReadEvent);
}
if (m_fds[i].revents & POLLOUT)
{
m_evLoop->eventActive(m_fds[i].fd, (int)FDEvent::WriteEvent);
}
}
return 0;
}