Software /
code /
prosody
Comparison
util-src/poll.c @ 11120:b2331f3dfeea
Merge 0.11->trunk
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Wed, 30 Sep 2020 09:50:33 +0100 |
parent | 10921:6eb5d2bb11af |
child | 12314:898554323338 |
comparison
equal
deleted
inserted
replaced
11119:68df52bf08d5 | 11120:b2331f3dfeea |
---|---|
35 #endif | 35 #endif |
36 | 36 |
37 #if (LUA_VERSION_NUM == 501) | 37 #if (LUA_VERSION_NUM == 501) |
38 #define luaL_setmetatable(L, tname) luaL_getmetatable(L, tname); lua_setmetatable(L, -2) | 38 #define luaL_setmetatable(L, tname) luaL_getmetatable(L, tname); lua_setmetatable(L, -2) |
39 #endif | 39 #endif |
40 #if (LUA_VERSION_NUM < 504) | |
41 #define luaL_pushfail lua_pushnil | |
42 #endif | |
40 | 43 |
41 /* | 44 /* |
42 * Structure to keep state for each type of API | 45 * Structure to keep state for each type of API |
43 */ | 46 */ |
44 typedef struct Lpoll_state { | 47 typedef struct Lpoll_state { |
57 } Lpoll_state; | 60 } Lpoll_state; |
58 | 61 |
59 /* | 62 /* |
60 * Add an FD to be watched | 63 * Add an FD to be watched |
61 */ | 64 */ |
62 int Ladd(lua_State *L) { | 65 static int Ladd(lua_State *L) { |
63 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); | 66 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); |
64 int fd = luaL_checkinteger(L, 2); | 67 int fd = luaL_checkinteger(L, 2); |
65 | 68 |
66 int wantread = lua_toboolean(L, 3); | 69 int wantread = lua_toboolean(L, 3); |
67 int wantwrite = lua_toboolean(L, 4); | 70 int wantwrite = lua_toboolean(L, 4); |
68 | 71 |
69 if(fd < 0) { | 72 if(fd < 0) { |
70 lua_pushnil(L); | 73 luaL_pushfail(L); |
71 lua_pushstring(L, strerror(EBADF)); | 74 lua_pushstring(L, strerror(EBADF)); |
72 lua_pushinteger(L, EBADF); | 75 lua_pushinteger(L, EBADF); |
73 return 3; | 76 return 3; |
74 } | 77 } |
75 | 78 |
82 | 85 |
83 int ret = epoll_ctl(state->epoll_fd, EPOLL_CTL_ADD, fd, &event); | 86 int ret = epoll_ctl(state->epoll_fd, EPOLL_CTL_ADD, fd, &event); |
84 | 87 |
85 if(ret < 0) { | 88 if(ret < 0) { |
86 ret = errno; | 89 ret = errno; |
87 lua_pushnil(L); | 90 luaL_pushfail(L); |
88 lua_pushstring(L, strerror(ret)); | 91 lua_pushstring(L, strerror(ret)); |
89 lua_pushinteger(L, ret); | 92 lua_pushinteger(L, ret); |
90 return 3; | 93 return 3; |
91 } | 94 } |
92 | 95 |
94 return 1; | 97 return 1; |
95 | 98 |
96 #else | 99 #else |
97 | 100 |
98 if(fd > FD_SETSIZE) { | 101 if(fd > FD_SETSIZE) { |
99 lua_pushnil(L); | 102 luaL_pushfail(L); |
100 lua_pushstring(L, strerror(EBADF)); | 103 lua_pushstring(L, strerror(EBADF)); |
101 lua_pushinteger(L, EBADF); | 104 lua_pushinteger(L, EBADF); |
102 return 3; | 105 return 3; |
103 } | 106 } |
104 | 107 |
105 if(FD_ISSET(fd, &state->all)) { | 108 if(FD_ISSET(fd, &state->all)) { |
106 lua_pushnil(L); | 109 luaL_pushfail(L); |
107 lua_pushstring(L, strerror(EEXIST)); | 110 lua_pushstring(L, strerror(EEXIST)); |
108 lua_pushinteger(L, EEXIST); | 111 lua_pushinteger(L, EEXIST); |
109 return 3; | 112 return 3; |
110 } | 113 } |
111 | 114 |
135 } | 138 } |
136 | 139 |
137 /* | 140 /* |
138 * Set events to watch for, readable and/or writable | 141 * Set events to watch for, readable and/or writable |
139 */ | 142 */ |
140 int Lset(lua_State *L) { | 143 static int Lset(lua_State *L) { |
141 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); | 144 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); |
142 int fd = luaL_checkinteger(L, 2); | 145 int fd = luaL_checkinteger(L, 2); |
143 | 146 |
144 #ifdef USE_EPOLL | 147 #ifdef USE_EPOLL |
145 | 148 |
158 lua_pushboolean(L, 1); | 161 lua_pushboolean(L, 1); |
159 return 1; | 162 return 1; |
160 } | 163 } |
161 else { | 164 else { |
162 ret = errno; | 165 ret = errno; |
163 lua_pushnil(L); | 166 luaL_pushfail(L); |
164 lua_pushstring(L, strerror(ret)); | 167 lua_pushstring(L, strerror(ret)); |
165 lua_pushinteger(L, ret); | 168 lua_pushinteger(L, ret); |
166 return 3; | 169 return 3; |
167 } | 170 } |
168 | 171 |
169 #else | 172 #else |
170 | 173 |
171 if(!FD_ISSET(fd, &state->all)) { | 174 if(!FD_ISSET(fd, &state->all)) { |
172 lua_pushnil(L); | 175 luaL_pushfail(L); |
173 lua_pushstring(L, strerror(ENOENT)); | 176 lua_pushstring(L, strerror(ENOENT)); |
174 lua_pushinteger(L, ENOENT); | 177 lua_pushinteger(L, ENOENT); |
178 return 3; | |
175 } | 179 } |
176 | 180 |
177 if(!lua_isnoneornil(L, 3)) { | 181 if(!lua_isnoneornil(L, 3)) { |
178 if(lua_toboolean(L, 3)) { | 182 if(lua_toboolean(L, 3)) { |
179 FD_SET(fd, &state->wantread); | 183 FD_SET(fd, &state->wantread); |
198 } | 202 } |
199 | 203 |
200 /* | 204 /* |
201 * Remove FDs | 205 * Remove FDs |
202 */ | 206 */ |
203 int Ldel(lua_State *L) { | 207 static int Ldel(lua_State *L) { |
204 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); | 208 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); |
205 int fd = luaL_checkinteger(L, 2); | 209 int fd = luaL_checkinteger(L, 2); |
206 | 210 |
207 #ifdef USE_EPOLL | 211 #ifdef USE_EPOLL |
208 | 212 |
215 lua_pushboolean(L, 1); | 219 lua_pushboolean(L, 1); |
216 return 1; | 220 return 1; |
217 } | 221 } |
218 else { | 222 else { |
219 ret = errno; | 223 ret = errno; |
220 lua_pushnil(L); | 224 luaL_pushfail(L); |
221 lua_pushstring(L, strerror(ret)); | 225 lua_pushstring(L, strerror(ret)); |
222 lua_pushinteger(L, ret); | 226 lua_pushinteger(L, ret); |
223 return 3; | 227 return 3; |
224 } | 228 } |
225 | 229 |
226 #else | 230 #else |
227 | 231 |
228 if(!FD_ISSET(fd, &state->all)) { | 232 if(!FD_ISSET(fd, &state->all)) { |
229 lua_pushnil(L); | 233 luaL_pushfail(L); |
230 lua_pushstring(L, strerror(ENOENT)); | 234 lua_pushstring(L, strerror(ENOENT)); |
231 lua_pushinteger(L, ENOENT); | 235 lua_pushinteger(L, ENOENT); |
236 return 3; | |
232 } | 237 } |
233 | 238 |
234 FD_CLR(fd, &state->wantread); | 239 FD_CLR(fd, &state->wantread); |
235 FD_CLR(fd, &state->wantwrite); | 240 FD_CLR(fd, &state->wantwrite); |
236 FD_CLR(fd, &state->readable); | 241 FD_CLR(fd, &state->readable); |
245 | 250 |
246 | 251 |
247 /* | 252 /* |
248 * Check previously manipulated event state for FDs ready for reading or writing | 253 * Check previously manipulated event state for FDs ready for reading or writing |
249 */ | 254 */ |
250 int Lpushevent(lua_State *L, struct Lpoll_state *state) { | 255 static int Lpushevent(lua_State *L, struct Lpoll_state *state) { |
251 #ifdef USE_EPOLL | 256 #ifdef USE_EPOLL |
252 | 257 |
253 if(state->processed > 0) { | 258 if(state->processed > 0) { |
254 state->processed--; | 259 state->processed--; |
255 struct epoll_event event = state->events[state->processed]; | 260 struct epoll_event event = state->events[state->processed]; |
279 } | 284 } |
280 | 285 |
281 /* | 286 /* |
282 * Wait for event | 287 * Wait for event |
283 */ | 288 */ |
284 int Lwait(lua_State *L) { | 289 static int Lwait(lua_State *L) { |
285 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); | 290 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); |
286 | 291 |
287 int ret = Lpushevent(L, state); | 292 int ret = Lpushevent(L, state); |
288 | 293 |
289 if(ret != 0) { | 294 if(ret != 0) { |
310 | 315 |
311 ret = select(FD_SETSIZE, &state->readable, &state->writable, &state->err, &tv); | 316 ret = select(FD_SETSIZE, &state->readable, &state->writable, &state->err, &tv); |
312 #endif | 317 #endif |
313 | 318 |
314 if(ret == 0) { | 319 if(ret == 0) { |
320 /* Is this an error? */ | |
315 lua_pushnil(L); | 321 lua_pushnil(L); |
316 lua_pushstring(L, "timeout"); | 322 lua_pushstring(L, "timeout"); |
317 return 2; | 323 return 2; |
318 } | 324 } |
319 else if(ret < 0 && errno == EINTR) { | 325 else if(ret < 0 && errno == EINTR) { |
326 /* Is this an error? */ | |
320 lua_pushnil(L); | 327 lua_pushnil(L); |
321 lua_pushstring(L, "signal"); | 328 lua_pushstring(L, "signal"); |
322 return 2; | 329 return 2; |
323 } | 330 } |
324 else if(ret < 0) { | 331 else if(ret < 0) { |
325 ret = errno; | 332 ret = errno; |
326 lua_pushnil(L); | 333 luaL_pushfail(L); |
327 lua_pushstring(L, strerror(ret)); | 334 lua_pushstring(L, strerror(ret)); |
328 lua_pushinteger(L, ret); | 335 lua_pushinteger(L, ret); |
329 return 3; | 336 return 3; |
330 } | 337 } |
331 | 338 |
342 | 349 |
343 #ifdef USE_EPOLL | 350 #ifdef USE_EPOLL |
344 /* | 351 /* |
345 * Return Epoll FD | 352 * Return Epoll FD |
346 */ | 353 */ |
347 int Lgetfd(lua_State *L) { | 354 static int Lgetfd(lua_State *L) { |
348 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); | 355 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); |
349 lua_pushinteger(L, state->epoll_fd); | 356 lua_pushinteger(L, state->epoll_fd); |
350 return 1; | 357 return 1; |
351 } | 358 } |
352 | 359 |
353 /* | 360 /* |
354 * Close epoll FD | 361 * Close epoll FD |
355 */ | 362 */ |
356 int Lgc(lua_State *L) { | 363 static int Lgc(lua_State *L) { |
357 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); | 364 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); |
358 | 365 |
359 if(state->epoll_fd == -1) { | 366 if(state->epoll_fd == -1) { |
360 return 0; | 367 return 0; |
361 } | 368 } |
373 #endif | 380 #endif |
374 | 381 |
375 /* | 382 /* |
376 * String representation | 383 * String representation |
377 */ | 384 */ |
378 int Ltos(lua_State *L) { | 385 static int Ltos(lua_State *L) { |
379 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); | 386 struct Lpoll_state *state = luaL_checkudata(L, 1, STATE_MT); |
380 lua_pushfstring(L, "%s: %p", STATE_MT, state); | 387 lua_pushfstring(L, "%s: %p", STATE_MT, state); |
381 return 1; | 388 return 1; |
382 } | 389 } |
383 | 390 |
384 /* | 391 /* |
385 * Create a new context | 392 * Create a new context |
386 */ | 393 */ |
387 int Lnew(lua_State *L) { | 394 static int Lnew(lua_State *L) { |
388 /* Allocate state */ | 395 /* Allocate state */ |
389 Lpoll_state *state = lua_newuserdata(L, sizeof(Lpoll_state)); | 396 Lpoll_state *state = lua_newuserdata(L, sizeof(Lpoll_state)); |
390 luaL_setmetatable(L, STATE_MT); | 397 luaL_setmetatable(L, STATE_MT); |
391 | 398 |
392 /* Initialize state */ | 399 /* Initialize state */ |
395 state->processed = 0; | 402 state->processed = 0; |
396 | 403 |
397 int epoll_fd = epoll_create1(EPOLL_CLOEXEC); | 404 int epoll_fd = epoll_create1(EPOLL_CLOEXEC); |
398 | 405 |
399 if(epoll_fd <= 0) { | 406 if(epoll_fd <= 0) { |
400 lua_pushnil(L); | 407 luaL_pushfail(L); |
401 lua_pushstring(L, strerror(errno)); | 408 lua_pushstring(L, strerror(errno)); |
402 lua_pushinteger(L, errno); | 409 lua_pushinteger(L, errno); |
403 return 3; | 410 return 3; |
404 } | 411 } |
405 | 412 |