equal
deleted
inserted
replaced
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); |