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