summaryrefslogtreecommitdiff
path: root/src/l_timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/l_timer.c')
-rw-r--r--src/l_timer.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/l_timer.c b/src/l_timer.c
new file mode 100644
index 0000000..129fd13
--- /dev/null
+++ b/src/l_timer.c
@@ -0,0 +1,119 @@
+/*
+ * gcsd
+ *
+ * gcsd the generic command sequencer daemon can be used to serialize
+ * commands sent over various paralell communication channels to a
+ * single command output. It can be seen as a multiplexer for any
+ * kind of communication between a single resource and various clients
+ * which want to submit commands to it or query information from it.
+ * gcsd is written in C and Lua. The goal is to provide an easy to
+ * understand high level API based on Lua which can be used to
+ * implement the business logic of the so formed multiplexer daemon.
+ *
+ *
+ * Copyright (C) 2009-2010 Markus Grueneis <gimpf@spreadspace.org>
+ * Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of gcsd.
+ *
+ * gcsd is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * gcsd is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gcsd. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include <sys/time.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "l_timer.h"
+
+#define LUA_TIMER_UDATA_NAME "struct timeval"
+
+static int l_timer_new(lua_State *L)
+{
+ int ms = luaL_optint(L, 1, 0);
+ struct timeval* tv = (struct timeval*)lua_newuserdata(L, sizeof(struct timeval));
+ luaL_newmetatable(L, LUA_TIMER_UDATA_NAME);
+ lua_setmetatable(L, -2);
+ tv->tv_sec = ms/1000;
+ tv->tv_usec = (ms%1000)*1000;
+ return 1;
+}
+
+static int l_timer_now(lua_State *L)
+{
+ struct timeval* now = (struct timeval*)lua_newuserdata(L, sizeof(struct timeval));
+ int ret = gettimeofday(now, NULL);
+ if(ret) {
+ lua_pushnil(L);
+ lua_pushstring(L, strerror(errno)); // FIXXXXXME: strerror is not threadsafe!!!
+ return 2;
+ }
+ luaL_newmetatable(L, LUA_TIMER_UDATA_NAME);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+static int l_timer_add(lua_State *L)
+{
+ struct timeval* a = (struct timeval*)luaL_checkudata(L, 1, LUA_TIMER_UDATA_NAME);
+ struct timeval* b = (struct timeval*)luaL_checkudata(L, 2, LUA_TIMER_UDATA_NAME);
+ struct timeval* res = (struct timeval*)lua_newuserdata(L, sizeof(struct timeval));
+ luaL_newmetatable(L, LUA_TIMER_UDATA_NAME);
+ lua_setmetatable(L, -2);
+ timeradd(a, b, res);
+ return 1;
+}
+
+static int l_timer_sub(lua_State *L)
+{
+ struct timeval* a = (struct timeval*)luaL_checkudata(L, 1, LUA_TIMER_UDATA_NAME);
+ struct timeval* b = (struct timeval*)luaL_checkudata(L, 2, LUA_TIMER_UDATA_NAME);
+ struct timeval* res = (struct timeval*)lua_newuserdata(L, sizeof(struct timeval));
+ luaL_newmetatable(L, LUA_TIMER_UDATA_NAME);
+ lua_setmetatable(L, -2);
+ timersub(a, b, res);
+ return 1;
+}
+
+static int l_timer_cmp(lua_State *L)
+{
+ struct timeval* a = (struct timeval*)luaL_checkudata(L, 1, LUA_TIMER_UDATA_NAME);
+ struct timeval* b = (struct timeval*)luaL_checkudata(L, 2, LUA_TIMER_UDATA_NAME);
+ if(timercmp(a, b, <))
+ lua_pushinteger(L, -1);
+ else if(timercmp(a, b, >))
+ lua_pushinteger(L, 1);
+ else
+ lua_pushinteger(L, 0);
+
+ return 1;
+}
+
+static const struct luaL_reg timer_funcs [] = {
+ { "new", l_timer_new },
+ { "now", l_timer_now },
+ { "add", l_timer_add },
+ { "sub", l_timer_sub },
+ { "cmp", l_timer_cmp },
+ { NULL, NULL }
+};
+
+LUALIB_API int luaopen_timer(lua_State *L)
+{
+ luaL_register(L, LUA_TIMERLIBNAME, timer_funcs);
+ return 1;
+}