From 6efa44f5058c99da150dd5af405f3cc937af9257 Mon Sep 17 00:00:00 2001 From: Axel Kittenberger Date: Wed, 10 Nov 2010 15:57:37 +0000 Subject: [PATCH] --- lsyncd.c | 101 ++++++++++++++++++++++++++++++--------------- lsyncd.lua | 118 +++++++++++++++++++++++++++++------------------------ 2 files changed, 132 insertions(+), 87 deletions(-) diff --git a/lsyncd.c b/lsyncd.c index f256384..c9ef018 100644 --- a/lsyncd.c +++ b/lsyncd.c @@ -840,7 +840,38 @@ static const luaL_reg lsyncdlib[] = { * Lsyncd Core ****************************************************************************/ +/** + * Dummy variable whos address is used as the cores index in the lua registry + * to the lua runners function table in the lua registry. + */ +static int runner; +/** + * Dummy variable whos address is used as the cores index n the lua registry + * to the lua runners error handler. + */ +static int callError; + +/** + * Pushes a function from the runner on the stack. + * Prior it pushed the callError handler. + */ +static void +load_runner_func(lua_State *L, const char *name) +{ + printlogf(L, "Call", "%s()", name); + + /* pushes the error handler */ + lua_pushlightuserdata(L, (void *) &callError); + lua_gettable(L, LUA_REGISTRYINDEX); + + /* pushes the function */ + lua_pushlightuserdata(L, (void *) &runner); + lua_gettable(L, LUA_REGISTRYINDEX); + lua_pushstring(L, name); + lua_gettable(L, -2); + lua_remove(L, -2); +} /** * Buffer for MOVE_FROM events. @@ -861,7 +892,8 @@ bool move_event = false; /** * Handles an inotify event. */ -void handle_event(lua_State *L, struct inotify_event *event) { +static void +handle_event(lua_State *L, struct inotify_event *event) { /* TODO */ int event_type = NONE; @@ -874,9 +906,7 @@ void handle_event(lua_State *L, struct inotify_event *event) { } if (event && (IN_Q_OVERFLOW & event->mask)) { /* and overflow happened, lets runner/user decide what to do. */ - printlogf(L, "Call", "overflow()"); - lua_getglobal(L, "lsyncd_call_error"); - lua_getglobal(L, "overflow"); + load_runner_func(L, "overflow"); if (lua_pcall(L, 0, 0, -2)) { exit(-1); // ERRNO } @@ -945,9 +975,7 @@ void handle_event(lua_State *L, struct inotify_event *event) { } /* and hands over to runner */ - printlogf(L, "Call", "lysncd_inotify_event()"); - lua_getglobal(L, "lsyncd_call_error"); - lua_getglobal(L, "lsyncd_inotify_event"); + load_runner_func(L, "inotify_event"); // TODO CamelCase switch(event_type) { case ATTRIB : lua_pushstring(L, "Attrib"); break; case MODIFY : lua_pushstring(L, "Modify"); break; @@ -982,7 +1010,7 @@ void handle_event(lua_State *L, struct inotify_event *event) { /** * Normal operation happens in here. */ -void +static void masterloop(lua_State *L) { size_t readbuf_size = 2048; @@ -995,9 +1023,7 @@ masterloop(lua_State *L) ssize_t len; /* queries runner about soonest alarm */ - printlogf(L, "Call", "lsycnd_get_alarm()"); - lua_getglobal(L, "lsyncd_call_error"); - lua_getglobal(L, "lsyncd_get_alarm"); + load_runner_func(L, "get_alarm"); // TODO CamelCase if (lua_pcall(L, 0, 1, -2)) { exit(-1); // ERRNO } @@ -1093,9 +1119,7 @@ masterloop(lua_State *L) if (pid <= 0) { break; } - printlogf(L, "Call", "lsyncd_collect_process()"); - lua_getglobal(L, "lsyncd_call_error"); - lua_getglobal(L, "lsyncd_collect_process"); + load_runner_func(L, "collect_process"); // TODO CamelCase lua_pushinteger(L, pid); lua_pushinteger(L, WEXITSTATUS(status)); if (lua_pcall(L, 2, 0, -4)) { @@ -1106,9 +1130,7 @@ masterloop(lua_State *L) /* lets the runner do stuff every cycle, * like starting new processes, writing the statusfile etc. */ - printlogf(L, "Call", "lsyncd_cycle()"); - lua_getglobal(L, "lsyncd_call_error"); - lua_getglobal(L, "lsyncd_cycle"); + load_runner_func(L, "cycle"); // TODO CamelCase lua_pushinteger(L, times(NULL)); if (lua_pcall(L, 1, 0, -3)) { exit(-1); // ERRNO @@ -1227,13 +1249,32 @@ main(int argc, char *argv[]) #endif } - /* executes the runner defining all its functions */ - if (lua_pcall(L, 0, LUA_MULTRET, 0)) { - printlogf(L, "Error", - "error preparing '%s': %s", - lsyncd_runner_file ? lsyncd_runner_file : "internal runner", - lua_tostring(L, -1)); - return -1; // ERRNO + { + /* place to store the lua runners functions */ + /* executes the runner defining all its functions */ + if (lua_pcall(L, 0, LUA_MULTRET, 0)) { + printlogf(L, "Error", + "error preparing '%s': %s", + lsyncd_runner_file ? lsyncd_runner_file : "internal runner", + lua_tostring(L, -1)); + return -1; // ERRNO + } + lua_pushlightuserdata(L, (void *)&runner); + /* switches the value (result of preparing) and the key &runner */ + lua_insert(L, 1); + /* saves the table of the runners functions in the lua registry */ + lua_settable(L, LUA_REGISTRYINDEX); + + /* saves the error function extra */ + /* &callError is the key */ + lua_pushlightuserdata(L, (void *) &callError); + /* &runner[callError] the value */ + lua_pushlightuserdata(L, (void *) &runner); + lua_gettable(L, LUA_REGISTRYINDEX); + lua_pushstring(L, "callError"); + lua_gettable(L, -2); + lua_remove(L, -2); + lua_settable(L, LUA_REGISTRYINDEX); } { @@ -1256,9 +1297,7 @@ main(int argc, char *argv[]) int i; for(i = argp; i < argc; i++) { if (!strcmp(argv[i],"-help") || !strcmp(argv[i],"--help")) { - logstring("Call", "lsyncd_help()"); - lua_getglobal(L, "lsyncd_call_error"); - lua_getglobal(L, "lsyncd_help"); + load_runner_func(L, "help"); if (lua_pcall(L, 0, 0, -2)) { exit(-1); // ERRNO } @@ -1273,9 +1312,7 @@ main(int argc, char *argv[]) int idx = 1; const char *s; /* creates a table with all remaining argv option arguments */ - logstring("Call", "lsyncd_configure()"); - lua_getglobal(L, "lsyncd_call_error"); - lua_getglobal(L, "lsyncd_configure"); + load_runner_func(L, "configure"); lua_newtable(L); while(argp < argc) { lua_pushnumber(L, idx++); @@ -1340,9 +1377,7 @@ main(int argc, char *argv[]) { /* runs initialitions from runner * lua code will set configuration and add watches */ - logstring("Call", "lsyncd_initalize()"); - lua_getglobal(L, "lsyncd_call_error"); - lua_getglobal(L, "lsyncd_initialize"); + load_runner_func(L, "initialize"); if (lua_pcall(L, 0, 0, -2)) { exit(-1); // ERRNO } diff --git a/lsyncd.lua b/lsyncd.lua index 30881a2..74737c0 100644 --- a/lsyncd.lua +++ b/lsyncd.lua @@ -959,45 +959,6 @@ local Inotifies = (function() } end)() ---============================================================================ --- lsyncd runner plugs. These functions will be called from core. ---============================================================================ - ------ --- true after lsyncd_initalized() --- -local running = false - ------ --- Called from core whenever a lua failed. --- -function lsyncd_call_error(message) - log("Error", "IN LUA: ", message) - -- prints backtrace - local level = 2 - while true do - local info = debug.getinfo(level, "Sl") - if not info then - terminate(-1) -- ERRNO - end - log("Error", "Backtrace ", level - 1, " :", - info.short_src, ":", info.currentline) - level = level + 1 - end -end - ------ --- Called from code whenever a child process finished and --- zombie process was collected by core. --- -function lsyncd_collect_process(pid, exitcode) - for _, s in Syncs.iwalk() do - if s:collect(pid, exitcode) then - return - end - end -end - ---- -- Writes a status report file at most every [statusintervall] seconds. @@ -1062,6 +1023,51 @@ local StatusFile = (function() return {write = write, getAlarm = getAlarm} end)() +--============================================================================ +-- lsyncd runner plugs. These functions will be called from core. +--============================================================================ + +----- +-- true after lsyncd_initalized() +-- TODO change to string +-- +local running = false + +---- +-- the cores interface to the runner +local runner = {} + +----- +-- Called from core whenever lua code failed. +-- Logs a backtrace +-- +function runner.callError(message) + log("Error", "IN LUA: ", message) + -- prints backtrace + local level = 2 + while true do + local info = debug.getinfo(level, "Sl") + if not info then + terminate(-1) -- ERRNO + end + log("Error", "Backtrace ", level - 1, " :", + info.short_src, ":", info.currentline) + level = level + 1 + end +end + +----- +-- Called from code whenever a child process finished and +-- zombie process was collected by core. +-- +function runner.collect_process(pid, exitcode) + for _, s in Syncs.iwalk() do + if s:collect(pid, exitcode) then + return + end + end +end + ---- -- Called from core everytime a masterloop cycle runs through. -- This happens in case of @@ -1072,7 +1078,7 @@ end)() -- -- @param now the current kernel time (in jiffies) -- -function lsyncd_cycle(now) +function runner.cycle(now) -- goes through all syncs and spawns more actions -- if possible for _, s in Syncs.iwalk() do @@ -1090,7 +1096,7 @@ end -- Called by core before anything is "-help" or "--help" is in -- the arguments. -- -function lsyncd_help() +function runner.help() io.stdout:write( [[ USAGE: @@ -1124,7 +1130,7 @@ end -- or simply 'true' if running with rsync bevaiour -- terminates on invalid arguments -- -function lsyncd_configure(args) +function runner.configure(args) -- a list of all valid --options local options = { -- log is handled by core already. @@ -1167,7 +1173,7 @@ end ---- -- Called from core on init or restart after user configuration. -- -function lsyncd_initialize() +function runner.initialize() -- creates settings if user didnt settings = settings or {} @@ -1209,7 +1215,7 @@ end -- true ... immediate action -- times ... the alarm time (only read if number is 1) -- -function lsyncd_get_alarm() +function runner.get_alarm() local alarm = false ---- @@ -1238,7 +1244,11 @@ function lsyncd_get_alarm() return alarm end -lsyncd_inotify_event = Inotifies.event + +----- +-- Called when an inotify event arrived. +-- Simply forwards it directly to the object. +runner.inotify_event = Inotifies.event ----- -- Collector for every child process that finished in startup phase @@ -1249,7 +1259,7 @@ lsyncd_inotify_event = Inotifies.event -- has been spawned as replacement (e.g. retry) or 0 if -- finished/ok. -- -function startup_collector(pid, exitcode) +function runner.collector(pid, exitcode) if exitcode ~= 0 then log("Error", "Startup process", pid, " failed") terminate(-1) -- ERRNO @@ -1257,6 +1267,13 @@ function startup_collector(pid, exitcode) return 0 end +---- +-- Called by core when an overflow happened. +-- +function runner.overflow() + log("Error", "--- OVERFLOW on inotify event queue ---") + terminate(-1) -- TODO reset instead. +end --============================================================================ -- lsyncd user interface @@ -1272,14 +1289,6 @@ function sync(opts) Syncs.add(opts) end ----- --- Called by core when an overflow happened. --- -function default_overflow() - log("Error", "--- OVERFLOW on inotify event queue ---") - terminate(-1) -- TODO reset instead. -end -overflow = default_overflow ----- -- Spawn a new child process @@ -1429,3 +1438,4 @@ default = { statusIntervall = 10, } +return runner