This source file includes following definitions.
- fpm_event_devpoll_module
- fpm_event_devpoll_init
- fpm_event_devpoll_clean
- fpm_event_devpoll_wait
- fpm_event_devpoll_add
- fpm_event_devpoll_remove
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include "../fpm_config.h"
22 #include "../fpm_events.h"
23 #include "../fpm.h"
24 #include "../zlog.h"
25
26 #if HAVE_DEVPOLL
27
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <poll.h>
32 #include <sys/devpoll.h>
33 #include <errno.h>
34
35 static int fpm_event_devpoll_init(int max);
36 static int fpm_event_devpoll_clean();
37 static int fpm_event_devpoll_wait(struct fpm_event_queue_s *queue, unsigned long int timeout);
38 static int fpm_event_devpoll_add(struct fpm_event_s *ev);
39 static int fpm_event_devpoll_remove(struct fpm_event_s *ev);
40
41 static struct fpm_event_module_s devpoll_module = {
42 .name = "/dev/poll",
43 .support_edge_trigger = 0,
44 .init = fpm_event_devpoll_init,
45 .clean = fpm_event_devpoll_clean,
46 .wait = fpm_event_devpoll_wait,
47 .add = fpm_event_devpoll_add,
48 .remove = fpm_event_devpoll_remove,
49 };
50
51 int dpfd = -1;
52 static struct pollfd *pollfds = NULL;
53 static struct pollfd *active_pollfds = NULL;
54 static int npollfds = 0;
55
56 #endif
57
58 struct fpm_event_module_s *fpm_event_devpoll_module()
59 {
60 #if HAVE_DEVPOLL
61 return &devpoll_module;
62 #else
63 return NULL;
64 #endif
65 }
66
67
68 #if HAVE_DEVPOLL
69
70
71
72
73 static int fpm_event_devpoll_init(int max)
74 {
75 int i;
76
77
78 dpfd = open("/dev/poll", O_RDWR);
79 if (dpfd < 0) {
80 zlog(ZLOG_ERROR, "Unable to open /dev/poll");
81 return -1;
82 }
83
84 if (max < 1) {
85 return 0;
86 }
87
88
89 pollfds = malloc(sizeof(struct pollfd) * max);
90 if (!pollfds) {
91 zlog(ZLOG_ERROR, "poll: unable to allocate %d events", max);
92 return -1;
93 }
94 memset(pollfds, 0, sizeof(struct pollfd) * max);
95
96
97 for (i = 0; i < max; i++) {
98 pollfds[i].fd = -1;
99 }
100
101
102 active_pollfds = malloc(sizeof(struct pollfd) * max);
103 if (!active_pollfds) {
104 free(pollfds);
105 zlog(ZLOG_ERROR, "poll: unable to allocate %d events", max);
106 return -1;
107 }
108 memset(active_pollfds, 0, sizeof(struct pollfd) * max);
109
110
111 npollfds = max;
112
113 return 0;
114 }
115
116
117
118
119
120 static int fpm_event_devpoll_clean()
121 {
122
123 if (dpfd > -1) {
124 close(dpfd);
125 dpfd = -1;
126 }
127
128
129 if (pollfds) {
130 free(pollfds);
131 pollfds = NULL;
132 }
133
134
135 if (active_pollfds) {
136 free(active_pollfds);
137 active_pollfds = NULL;
138 }
139
140 npollfds = 0;
141 return 0;
142 }
143
144
145
146
147
148 static int fpm_event_devpoll_wait(struct fpm_event_queue_s *queue, unsigned long int timeout)
149 {
150 int ret, i;
151 struct fpm_event_queue_s *q;
152 struct dvpoll dopoll;
153
154
155 dopoll.dp_fds = active_pollfds;
156 dopoll.dp_nfds = npollfds;
157 dopoll.dp_timeout = (int)timeout;
158
159
160 ret = ioctl(dpfd, DP_POLL, &dopoll);
161
162 if (ret < 0) {
163
164
165 if (errno != EINTR) {
166 zlog(ZLOG_WARNING, "/dev/poll: ioctl() returns %d", errno);
167 return -1;
168 }
169 }
170
171
172 for (i = 0; i < ret; i++) {
173
174
175 q = queue;
176 while (q) {
177
178
179 if (q->ev && q->ev->fd == active_pollfds[i].fd) {
180
181
182 fpm_event_fire(q->ev);
183
184
185 if (fpm_globals.parent_pid != getpid()) {
186 return -2;
187 }
188 break;
189 }
190 q = q->next;
191 }
192 }
193
194 return ret;
195 }
196
197
198
199
200
201 static int fpm_event_devpoll_add(struct fpm_event_s *ev)
202 {
203 struct pollfd pollfd;
204
205
206 pollfd.fd = ev->fd;
207 pollfd.events = POLLIN;
208 pollfd.revents = 0;
209
210
211 if (write(dpfd, &pollfd, sizeof(struct pollfd)) != sizeof(struct pollfd)) {
212 zlog(ZLOG_ERROR, "/dev/poll: Unable to add the event in the internal queue");
213 return -1;
214 }
215
216
217 ev->index = ev->fd;
218
219 return 0;
220 }
221
222
223
224
225
226 static int fpm_event_devpoll_remove(struct fpm_event_s *ev)
227 {
228 struct pollfd pollfd;
229
230
231 pollfd.fd = ev->fd;
232 pollfd.events = POLLIN | POLLREMOVE;
233 pollfd.revents = 0;
234
235
236 if (write(dpfd, &pollfd, sizeof(struct pollfd)) != sizeof(struct pollfd)) {
237 zlog(ZLOG_ERROR, "/dev/poll: Unable to remove the event in the internal queue");
238 return -1;
239 }
240
241
242 ev->index = -1;
243
244 return 0;
245 }
246
247
248 #endif