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);