src/lua_objs.c
branchlua-threads
changeset 203 ffdf53fd0337
parent 195 42aedce3e2eb
child 207 3fa22abb5421
--- a/src/lua_objs.c	Wed May 20 22:52:01 2009 +0300
+++ b/src/lua_objs.c	Wed May 20 22:53:05 2009 +0300
@@ -1,5 +1,6 @@
 #include "lua_objs.h"
 #include "lua_irc.h"
+#include "lua_func.h"
 #include "log.h"
 
 #include <stdlib.h>
@@ -338,10 +339,47 @@
     return 0;
 }
 
+static struct lua_func lua_nexus_sleep_func = LUA_FUNC(&lua_nexus_type, "sleep",
+        "Schedules itself to resume after the given delay (in seconds) and yields",
+
+        LUA_FUNC_ARG_INT("tv_sec",  LUA_ARG_REQUIRED)
+    );
+
+static void lua_nexus_sleep_wakeup (evutil_socket_t fd, short what, void *arg)
+{
+    lua_State *L = arg;
+
+    (void) fd;
+    (void) what;
+
+    // resume the thread that called lua_nexus_sleep
+    lua_thread_resume_state(L);
+}
+
+static int lua_nexus_sleep (lua_State *L)
+{
+    struct lua_nexus *lua_nexus;
+    long tv_sec;
+
+    // parse args
+    lua_args_parse(L, &lua_nexus_sleep_func, (void *) &lua_nexus, &tv_sec);
+
+    // build tv
+    struct timeval tv = { tv_sec, 0 };
+    
+    // schedule wakeup
+    // use a pure-timeout event
+    if (event_base_once(lua_nexus->nexus->ev_base, -1, 0, lua_nexus_sleep_wakeup, L, &tv))
+        return luaL_error(L, "event_base_once");
+
+    // yield
+    return lua_yield(L, 0);
+}
 
 static struct lua_method lua_nexus_methods[] = LUA_METHODS(
-        LUA_METHOD("shutdown",      lua_nexus_shutdown,     NULL    ),
-        LUA_METHOD("load_config",   lua_nexus_load_config,  NULL    )
+        LUA_METHOD("shutdown",      lua_nexus_shutdown,     NULL                    ),
+        LUA_METHOD("load_config",   lua_nexus_load_config,  NULL                    ),
+        LUA_METHOD("sleep",         lua_nexus_sleep,        &lua_nexus_sleep_func   )
     );
 
 /**
@@ -389,8 +427,8 @@
 }
 
 static const struct luaL_Reg lua_global_functions[] = {
-    {   "log_level",    &lua_log_level              },
-    {   "log",          &lua_log                    },
+    {   "log_level",    lua_log_level               },
+    {   "log",          lua_log                     },
     {   NULL,           NULL                        }
 };