8 #if LUA_VERSION_NUM != 503
9 #error only Lua 5.3 supported
12 #define TIMEOUT_PUBLIC static
16 #define TIMEOUT_METANAME "struct timeout"
17 #define TIMEOUTS_METANAME "struct timeouts*"
20 to_checkudata(lua_State *L,
int index)
22 return luaL_checkudata(L, index, TIMEOUT_METANAME);
26 tos_checkudata(lua_State *L,
int index)
28 return *(
struct timeouts **)luaL_checkudata(L, index, TIMEOUTS_METANAME);
32 tos_bind(lua_State *L,
int tos_index,
int to_index)
34 lua_getuservalue(L, tos_index);
35 lua_pushlightuserdata(L, to_checkudata(L, to_index));
36 lua_pushvalue(L, to_index);
42 tos_unbind(lua_State *L,
int tos_index,
int to_index)
44 lua_getuservalue(L, tos_index);
45 lua_pushlightuserdata(L, to_checkudata(L, to_index));
52 to__index(lua_State *L)
54 struct timeout *to = to_checkudata(L, 1);
56 if (lua_type(L, 2 == LUA_TSTRING)) {
57 const char *key = lua_tostring(L, 2);
59 if (!strcmp(key,
"flags")) {
60 lua_pushinteger(L, to->flags);
63 }
else if (!strcmp(key,
"expires")) {
64 lua_pushinteger(L, to->expires);
70 if (LUA_TNIL != lua_getuservalue(L, 1)) {
72 if (LUA_TNIL != lua_rawget(L, -2))
77 if (LUA_TNIL != lua_rawget(L, lua_upvalueindex(1)))
84 to__newindex(lua_State *L)
86 if (LUA_TNIL == lua_getuservalue(L, 1)) {
89 lua_setuservalue(L, 1);
102 struct timeout *to = to_checkudata(L, 1);
117 int flags = luaL_optinteger(L, 1, 0);
120 to = lua_newuserdata(L,
sizeof *to);
121 timeout_init(to, flags);
122 luaL_setmetatable(L, TIMEOUT_METANAME);
127 static const luaL_Reg to_methods[] = {
131 static const luaL_Reg to_metatable[] = {
132 {
"__index", &to__index },
133 {
"__newindex", &to__newindex },
138 static const luaL_Reg to_globals[] = {
144 to_newmetatable(lua_State *L)
146 if (luaL_newmetatable(L, TIMEOUT_METANAME)) {
151 luaL_newlib(L, to_methods);
152 luaL_setfuncs(L, to_metatable, 1);
157 luaopen_timeout(lua_State *L)
161 luaL_newlib(L, to_globals);
162 lua_pushinteger(L, TIMEOUT_INT);
163 lua_setfield(L, -2,
"INT");
164 lua_pushinteger(L, TIMEOUT_ABS);
165 lua_setfield(L, -2,
"ABS");
171 tos_update(lua_State *L)
173 struct timeouts *
T = tos_checkudata(L, 1);
174 lua_Number n = luaL_checknumber(L, 2);
176 timeouts_update(
T, timeouts_f2i(
T, n));
184 tos_step(lua_State *L)
186 struct timeouts *
T = tos_checkudata(L, 1);
187 lua_Number n = luaL_checknumber(L, 2);
189 timeouts_step(
T, timeouts_f2i(
T, n));
197 tos_timeout(lua_State *L)
199 struct timeouts *
T = tos_checkudata(L, 1);
201 lua_pushnumber(L, timeouts_i2f(
T, timeouts_timeout(
T)));
207 tos_add(lua_State *L)
209 struct timeouts *
T = tos_checkudata(L, 1);
210 struct timeout *to = to_checkudata(L, 2);
211 lua_Number
timeout = luaL_checknumber(L, 3);
216 return lua_pushvalue(L, 1), 1;
220 tos_del(lua_State *L)
222 struct timeouts *
T = tos_checkudata(L, 1);
223 struct timeout *to = to_checkudata(L, 2);
228 return lua_pushvalue(L, 1), 1;
232 tos_get(lua_State *L)
234 struct timeouts *
T = tos_checkudata(L, 1);
237 if (!(to = timeouts_get(
T)))
240 lua_getuservalue(L, 1);
241 lua_rawgetp(L, -1, to);
243 if (!timeout_pending(to))
244 tos_unbind(L, 1, lua_absindex(L, -1));
250 tos_pending(lua_State *L)
252 struct timeouts *
T = tos_checkudata(L, 1);
254 lua_pushboolean(L, timeouts_pending(
T));
260 tos_expired(lua_State *L)
262 struct timeouts *
T = tos_checkudata(L, 1);
264 lua_pushboolean(L, timeouts_expired(
T));
270 tos_check(lua_State *L)
272 struct timeouts *
T = tos_checkudata(L, 1);
274 lua_pushboolean(L, timeouts_check(
T, NULL));
280 tos__next(lua_State *L)
282 struct timeouts *
T = tos_checkudata(L, lua_upvalueindex(1));
283 struct timeouts_it *it = lua_touserdata(L, lua_upvalueindex(2));
286 if (!(to = timeouts_next(
T, it)))
289 lua_getuservalue(L, lua_upvalueindex(1));
290 lua_rawgetp(L, -1, to);
296 tos_timeouts(lua_State *L)
298 int flags = luaL_checkinteger(L, 2);
301 tos_checkudata(L, 1);
303 it = lua_newuserdata(L,
sizeof *it);
304 TIMEOUTS_IT_INIT(it, flags);
305 lua_pushcclosure(L, &tos__next, 2);
311 tos__gc(lua_State *L)
313 struct timeouts **tos = luaL_checkudata(L, 1, TIMEOUTS_METANAME);
316 TIMEOUTS_FOREACH(to, *tos, TIMEOUTS_ALL) {
317 timeouts_del(*tos, to);
320 timeouts_close(*tos);
327 tos_new(lua_State *L)
329 timeout_t hz = luaL_optinteger(L, 1, 0);
333 T = lua_newuserdata(L,
sizeof *
T);
334 luaL_setmetatable(L, TIMEOUTS_METANAME);
337 lua_setuservalue(L, -2);
339 if (!(*
T = timeouts_open(hz, &error)))
340 return luaL_error(L,
"%s", strerror(error));
345 static const luaL_Reg tos_methods[] = {
346 {
"update", &tos_update },
347 {
"step", &tos_step },
348 {
"timeout", &tos_timeout },
352 {
"pending", &tos_pending },
353 {
"expired", &tos_expired },
354 {
"check", &tos_check },
355 {
"timeouts", &tos_timeouts },
359 static const luaL_Reg tos_metatable[] = {
360 {
"__gc", &tos__gc },
364 static const luaL_Reg tos_globals[] = {
370 tos_newmetatable(lua_State *L)
372 if (luaL_newmetatable(L, TIMEOUTS_METANAME)) {
373 luaL_setfuncs(L, tos_metatable, 0);
374 luaL_newlib(L, tos_methods);
375 lua_setfield(L, -2,
"__index");
380 luaopen_timeouts(lua_State *L)
385 luaL_newlib(L, tos_globals);
386 lua_pushinteger(L, TIMEOUTS_PENDING);
387 lua_setfield(L, -2,
"PENDING");
388 lua_pushinteger(L, TIMEOUTS_EXPIRED);
389 lua_setfield(L, -2,
"EXPIRED");
390 lua_pushinteger(L, TIMEOUTS_ALL);
391 lua_setfield(L, -2,
"ALL");
392 lua_pushinteger(L, TIMEOUTS_CLEAR);
393 lua_setfield(L, -2,
"CLEAR");