Software /
code /
prosody
Comparison
util-src/poll.c @ 12314:898554323338
util.poll: Restructure to make adding additional system APIs easier
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Wed, 23 Feb 2022 20:30:22 +0100 |
parent | 10921:6eb5d2bb11af |
child | 12315:cf2086a1bd45 |
comparison
equal
deleted
inserted
replaced
12313:469e4453ed01 | 12314:898554323338 |
---|---|
10 | 10 |
11 #include <unistd.h> | 11 #include <unistd.h> |
12 #include <string.h> | 12 #include <string.h> |
13 #include <errno.h> | 13 #include <errno.h> |
14 | 14 |
15 #ifdef __linux__ | 15 #if defined(__linux__) |
16 #define USE_EPOLL | 16 #define USE_EPOLL |
17 #else | |
18 #define USE_SELECT | |
17 #endif | 19 #endif |
18 | 20 |
19 #ifdef USE_EPOLL | 21 #ifdef USE_EPOLL |
20 #include <sys/epoll.h> | 22 #include <sys/epoll.h> |
21 #ifndef MAX_EVENTS | 23 #ifndef MAX_EVENTS |
22 #define MAX_EVENTS 64 | 24 #define MAX_EVENTS 64 |
23 #endif | 25 #endif |
24 #else | 26 #endif |
27 #ifdef USE_SELECT | |
25 #include <sys/select.h> | 28 #include <sys/select.h> |
26 #endif | 29 #endif |
27 | 30 |
28 #include <lualib.h> | 31 #include <lualib.h> |
29 #include <lauxlib.h> | 32 #include <lauxlib.h> |
30 | 33 |
31 #ifdef USE_EPOLL | 34 #ifdef USE_EPOLL |
32 #define STATE_MT "util.poll<epoll>" | 35 #define STATE_MT "util.poll<epoll>" |
33 #else | 36 #endif |
37 #ifdef USE_SELECT | |
34 #define STATE_MT "util.poll<select>" | 38 #define STATE_MT "util.poll<select>" |
35 #endif | 39 #endif |
36 | 40 |
37 #if (LUA_VERSION_NUM == 501) | 41 #if (LUA_VERSION_NUM == 501) |
38 #define luaL_setmetatable(L, tname) luaL_getmetatable(L, tname); lua_setmetatable(L, -2) | 42 #define luaL_setmetatable(L, tname) luaL_getmetatable(L, tname); lua_setmetatable(L, -2) |
47 typedef struct Lpoll_state { | 51 typedef struct Lpoll_state { |
48 int processed; | 52 int processed; |
49 #ifdef USE_EPOLL | 53 #ifdef USE_EPOLL |
50 int epoll_fd; | 54 int epoll_fd; |
51 struct epoll_event events[MAX_EVENTS]; | 55 struct epoll_event events[MAX_EVENTS]; |
52 #else | 56 #endif |
57 #ifdef USE_SELECT | |
53 fd_set wantread; | 58 fd_set wantread; |
54 fd_set wantwrite; | 59 fd_set wantwrite; |
55 fd_set readable; | 60 fd_set readable; |
56 fd_set writable; | 61 fd_set writable; |
57 fd_set all; | 62 fd_set all; |
94 } | 99 } |
95 | 100 |
96 lua_pushboolean(L, 1); | 101 lua_pushboolean(L, 1); |
97 return 1; | 102 return 1; |
98 | 103 |
99 #else | 104 #endif |
105 #ifdef USE_SELECT | |
100 | 106 |
101 if(fd > FD_SETSIZE) { | 107 if(fd > FD_SETSIZE) { |
102 luaL_pushfail(L); | 108 luaL_pushfail(L); |
103 lua_pushstring(L, strerror(EBADF)); | 109 lua_pushstring(L, strerror(EBADF)); |
104 lua_pushinteger(L, EBADF); | 110 lua_pushinteger(L, EBADF); |
167 lua_pushstring(L, strerror(ret)); | 173 lua_pushstring(L, strerror(ret)); |
168 lua_pushinteger(L, ret); | 174 lua_pushinteger(L, ret); |
169 return 3; | 175 return 3; |
170 } | 176 } |
171 | 177 |
172 #else | 178 #endif |
179 #ifdef USE_SELECT | |
173 | 180 |
174 if(!FD_ISSET(fd, &state->all)) { | 181 if(!FD_ISSET(fd, &state->all)) { |
175 luaL_pushfail(L); | 182 luaL_pushfail(L); |
176 lua_pushstring(L, strerror(ENOENT)); | 183 lua_pushstring(L, strerror(ENOENT)); |
177 lua_pushinteger(L, ENOENT); | 184 lua_pushinteger(L, ENOENT); |
225 lua_pushstring(L, strerror(ret)); | 232 lua_pushstring(L, strerror(ret)); |
226 lua_pushinteger(L, ret); | 233 lua_pushinteger(L, ret); |
227 return 3; | 234 return 3; |
228 } | 235 } |
229 | 236 |
230 #else | 237 #endif |
238 #ifdef USE_SELECT | |
231 | 239 |
232 if(!FD_ISSET(fd, &state->all)) { | 240 if(!FD_ISSET(fd, &state->all)) { |
233 luaL_pushfail(L); | 241 luaL_pushfail(L); |
234 lua_pushstring(L, strerror(ENOENT)); | 242 lua_pushstring(L, strerror(ENOENT)); |
235 lua_pushinteger(L, ENOENT); | 243 lua_pushinteger(L, ENOENT); |
262 lua_pushboolean(L, event.events & (EPOLLIN | EPOLLHUP | EPOLLRDHUP | EPOLLERR)); | 270 lua_pushboolean(L, event.events & (EPOLLIN | EPOLLHUP | EPOLLRDHUP | EPOLLERR)); |
263 lua_pushboolean(L, event.events & EPOLLOUT); | 271 lua_pushboolean(L, event.events & EPOLLOUT); |
264 return 3; | 272 return 3; |
265 } | 273 } |
266 | 274 |
267 #else | 275 #endif |
276 #ifdef USE_SELECT | |
268 | 277 |
269 for(int fd = state->processed + 1; fd < FD_SETSIZE; fd++) { | 278 for(int fd = state->processed + 1; fd < FD_SETSIZE; fd++) { |
270 if(FD_ISSET(fd, &state->readable) || FD_ISSET(fd, &state->writable) || FD_ISSET(fd, &state->err)) { | 279 if(FD_ISSET(fd, &state->readable) || FD_ISSET(fd, &state->writable) || FD_ISSET(fd, &state->err)) { |
271 lua_pushinteger(L, fd); | 280 lua_pushinteger(L, fd); |
272 lua_pushboolean(L, FD_ISSET(fd, &state->readable) | FD_ISSET(fd, &state->err)); | 281 lua_pushboolean(L, FD_ISSET(fd, &state->readable) | FD_ISSET(fd, &state->err)); |
298 lua_Number timeout = luaL_checknumber(L, 2); | 307 lua_Number timeout = luaL_checknumber(L, 2); |
299 luaL_argcheck(L, timeout >= 0, 1, "positive number expected"); | 308 luaL_argcheck(L, timeout >= 0, 1, "positive number expected"); |
300 | 309 |
301 #ifdef USE_EPOLL | 310 #ifdef USE_EPOLL |
302 ret = epoll_wait(state->epoll_fd, state->events, MAX_EVENTS, timeout * 1000); | 311 ret = epoll_wait(state->epoll_fd, state->events, MAX_EVENTS, timeout * 1000); |
303 #else | 312 #endif |
313 #ifdef USE_SELECT | |
304 /* | 314 /* |
305 * select(2) mutates the fd_sets passed to it so in order to not | 315 * select(2) mutates the fd_sets passed to it so in order to not |
306 * have to recreate it manually every time a copy is made. | 316 * have to recreate it manually every time a copy is made. |
307 */ | 317 */ |
308 memcpy(&state->readable, &state->wantread, sizeof(fd_set)); | 318 memcpy(&state->readable, &state->wantread, sizeof(fd_set)); |
339 /* | 349 /* |
340 * Search for the first ready FD and return it | 350 * Search for the first ready FD and return it |
341 */ | 351 */ |
342 #ifdef USE_EPOLL | 352 #ifdef USE_EPOLL |
343 state->processed = ret; | 353 state->processed = ret; |
344 #else | 354 #endif |
355 #ifdef USE_SELECT | |
345 state->processed = -1; | 356 state->processed = -1; |
346 #endif | 357 #endif |
347 return Lpushevent(L, state); | 358 return Lpushevent(L, state); |
348 } | 359 } |
349 | 360 |
409 lua_pushinteger(L, errno); | 420 lua_pushinteger(L, errno); |
410 return 3; | 421 return 3; |
411 } | 422 } |
412 | 423 |
413 state->epoll_fd = epoll_fd; | 424 state->epoll_fd = epoll_fd; |
414 #else | 425 #endif |
426 #ifdef USE_SELECT | |
415 FD_ZERO(&state->wantread); | 427 FD_ZERO(&state->wantread); |
416 FD_ZERO(&state->wantwrite); | 428 FD_ZERO(&state->wantwrite); |
417 FD_ZERO(&state->readable); | 429 FD_ZERO(&state->readable); |
418 FD_ZERO(&state->writable); | 430 FD_ZERO(&state->writable); |
419 FD_ZERO(&state->all); | 431 FD_ZERO(&state->all); |