From 1c1c0ee54298683c7c2eda9c950bc2e53896e80a Mon Sep 17 00:00:00 2001 From: Axel Kittenberger Date: Sun, 24 Oct 2010 16:41:58 +0000 Subject: [PATCH] --- lsyncd-conf.lua | 4 +++- lsyncd.c | 61 +++++++++++++++++++++++++++++++++++++------------ lsyncd.lua | 48 ++++++++++++++++++++++++-------------- 3 files changed, 81 insertions(+), 32 deletions(-) diff --git a/lsyncd-conf.lua b/lsyncd-conf.lua index bd53216..669981d 100644 --- a/lsyncd-conf.lua +++ b/lsyncd-conf.lua @@ -14,8 +14,10 @@ print(bla) ------ -- for testing purposes -- -slower = "sleep 10 && " +slower = "sleep 1 && " slowbash = { + delay = 5, + startup = function(source, target) log(NORMAL, "cp -r from "..source.." -> "..target) return exec("/bin/bash", "-c", "cp -r \"$1\"* \"$2\"", "/bin/bash", diff --git a/lsyncd.c b/lsyncd.c index 8e41cc3..75b2a1c 100644 --- a/lsyncd.c +++ b/lsyncd.c @@ -323,6 +323,37 @@ l_log(lua_State *L) return 0; } +/** + * Returns (on Lua stack) true if time1 is earler or eq to time2 + * @param (on Lua Stack) time1 + * @param (on Lua Stack) time2 + * @return the true if time1 <= time2 + */ +static int +l_before_eq(lua_State *L) +{ + clock_t t1 = (clock_t) luaL_checkinteger(L, 1); + clock_t t2 = (clock_t) luaL_checkinteger(L, 2); + lua_pushboolean(L, time_before_eq(t1, t2)); + return 1; +} + +/** + * Returns (on Lua stack) the earlier or two clock times. + * + * @param (on Lua Stack) time1 + * @param (on Lua Stack) time2 + * @return the earlier time + */ +static int +l_earlier(lua_State *L) +{ + clock_t t1 = (clock_t) luaL_checkinteger(L, 1); + clock_t t2 = (clock_t) luaL_checkinteger(L, 2); + lua_pushinteger(L, time_before(t1, t2) ? t1 : t2); + return 1; +} + /** * Returns (on Lua stack) the current kernels clock state (jiffies, times() call) */ @@ -628,11 +659,13 @@ l_wait_pids(lua_State *L) static const luaL_reg lsyncdlib[] = { - {"addup_clocks", l_addup_clocks }, {"add_watch", l_add_watch }, + {"addup_clocks", l_addup_clocks }, + {"before_eq", l_before_eq }, + {"earlier", l_earlier }, + {"exec", l_exec }, {"log", l_log }, {"now", l_now }, - {"exec", l_exec }, {"real_dir", l_real_dir }, {"stackdump", l_stackdump }, {"sub_dirs", l_sub_dirs }, @@ -793,6 +826,7 @@ void handle_event(lua_State *L, struct inotify_event *event) { lua_pushnumber(L, event_type); lua_pushnumber(L, event->wd); lua_pushboolean(L, (event->mask & IN_ISDIR) != 0); + lua_pushinteger(L, times(NULL)); if (event_type == MOVE) { lua_pushstring(L, move_event_buf->name); lua_pushstring(L, event->name); @@ -800,7 +834,7 @@ void handle_event(lua_State *L, struct inotify_event *event) { lua_pushstring(L, event->name); lua_pushnil(L); } - lua_call(L, 5, 0); + lua_call(L, 6, 0); /* if there is a buffered event executes it */ if (after_buf) { @@ -817,7 +851,7 @@ masterloop(lua_State *L) size_t readbuf_size = 2048; char *readbuf = s_malloc(readbuf_size); while(!reset) { - int alarm_state; + bool have_alarm; clock_t now = times(NULL); clock_t alarm_time; bool do_read = false; @@ -825,18 +859,17 @@ masterloop(lua_State *L) /* query runner about soonest alarm */ lua_getglobal(L, "lsyncd_get_alarm"); - lua_pushnumber(L, now); - lua_call(L, 1, 2); - alarm_state = luaL_checkinteger(L, -2); - alarm_time = (clock_t) luaL_checknumber(L, -1); + lua_call(L, 0, 2); + have_alarm = lua_toboolean(L, -2); + alarm_time = (clock_t) luaL_checkinteger(L, -1); lua_pop(L, 2); - if (alarm_state < 0) { + if (have_alarm && time_before(alarm_time, now)) { /* there is a delay that wants to be handled already * thus do not read from inotify_fd and jump directly to its handling */ logstring(DEBUG, "immediately handling delayed entries."); do_read = 0; - } else if (alarm_state > 0) { + } else if (have_alarm) { /* use select() to determine what happens next * + a new event on inotify * + an alarm on timeout @@ -844,7 +877,7 @@ masterloop(lua_State *L) fd_set readfds; struct timeval tv; - if (time_after(now, alarm_time)) { + if (time_before(alarm_time, now)) { /* should never happen */ logstring(ERROR, "critical failure, alarm_time is in past!\n"); exit(-1); //ERRNO @@ -852,8 +885,8 @@ masterloop(lua_State *L) tv.tv_sec = (alarm_time - now) / clocks_per_sec; tv.tv_usec = (alarm_time - now) * 1000000 / clocks_per_sec % 1000000; - /* if select returns a positive number there is data on inotify * - * on zero the timemout occured. */ + /* if select returns a positive number there is data on inotify + * on zero the timemout occured. */ FD_ZERO(&readfds); FD_SET(inotify_fd, &readfds); do_read = select(inotify_fd + 1, &readfds, NULL, NULL, &tv); @@ -864,7 +897,7 @@ masterloop(lua_State *L) logstring(DEBUG, "core: select() timeout or signal."); } } else { - // if nothing to wait for, enter a blocking read + /* if nothing to wait for, enter a blocking read */ logstring(DEBUG, "gone blocking."); do_read = 1; } diff --git a/lsyncd.lua b/lsyncd.lua index 2bf549b..82bf42d 100644 --- a/lsyncd.lua +++ b/lsyncd.lua @@ -40,6 +40,7 @@ exec = lsyncd.exec -- .processes = [pid] .. a sublist of processes[] for this target -- .delays = [#) { .. the delays stack -- .atype .. enum, kind of action +-- .alarm .. when it should fire -- .wd .. watch descriptor id this origins from TODO needed? -- .sync .. link to sync that raised this delay. -- .filename .. filename or nil (=dir itself) @@ -114,7 +115,9 @@ local function delay_action(atype, wd, sync, filename, time) sync = sync, filename = filename } if time ~= nil and origin.actions.delay ~= nil then - nd.alarm = lsyncd.append_time(time, origin.actions.delay) + nd.alarm = lsyncd.addup_clocks(time, origin.actions.delay) + else + nd.alarm = lsyncd.now() end table.insert(delays, nd) end @@ -169,7 +172,7 @@ function lsyncd_collect_process(pid, exitcode) end local sync = process.sync local origin = sync.origin - print("collected ", pid, ": ", vent_names[atpye], origin.source, "/", sync.path , process.filename, " = ", exitcode) + print("collected ", pid, ": ", event_names[atpye], origin.source, "/", sync.path , process.filename, " = ", exitcode) processes[pid] = nil origin.processes[pid] = nil end @@ -226,19 +229,12 @@ local function invoke_action(delay) end end --- .delays = [#) { .. the delays stack --- .atype .. enum, kind of action --- .wd .. watch descriptor id this origins from TODO needed? --- .attend .. link to atttender that raised this delay. --- .filename .. filename or nil (=dir itself) --- (.movepeer) .. for MOVEFROM/MOVETO link to other delay - ---- -- Called from core everytime at the latest of an -- expired alarm (or more often) -- --- @param now the time is now +-- @param now the time now -- function lsyncd_alarm(now) -- goes through all targets and spawns more actions @@ -246,7 +242,7 @@ function lsyncd_alarm(now) for i, o in ipairs(origins) do if #o.processes < o.actions.max_processes then local delays = o.delays - if delays[1] ~= nil then + if delays[1] ~= nil and lsyncd.before_eq(delays[1].alarm, now) then invoke_action(o.delays[1]) table.remove(delays, 1) end @@ -310,12 +306,30 @@ end -- Called by core to query soonest alarm. -- -- @return two variables. --- number -1 means ... alarm is in the past. --- 0 means ... no alarm, core can in untimed sleep --- 1 means ... alarm time specified. +-- boolean false ... no alarm, core can in untimed sleep +-- true ... alarm time specified. -- times ... the alarm time (only read if number is 1) function lsyncd_get_alarm() - return 0, 0 + local have_alarm = false + local alarm = 0 + for i, o in ipairs(origins) do + if o.delays[1] ~= nil then + if have_alarm then + alarm = lsyncd.earlier(alarm, o.delays[1].alarm) + else + alarm = o.delays[1].alarm + have_alarm = true + end + end + end + local hs + if have_alarm then + hs = "true" + else + hs = "false" + end + log(DEBUG, "lsyncd_get_alarm ("..hs..","..alarm..")") + return have_alarm, alarm end ----- @@ -323,10 +337,11 @@ end -- -- @param etype enum (ATTRIB, MODIFY, CREATE, DELETE, MOVE) -- @param wd watch descriptor (matches lsyncd.add_watch()) +-- @param time time of event -- @param filename string filename without path -- @param filename2 -- -function lsyncd_event(etype, wd, isdir, filename, filename2) +function lsyncd_event(etype, wd, isdir, time, filename, filename2) local ftype; if isdir then ftype = "directory" @@ -349,7 +364,6 @@ function lsyncd_event(etype, wd, isdir, filename, filename2) -- works through all possible source->target pairs for i, sync in ipairs(w.syncs) do - time = nil -- TODO delay_action(etype, wd, sync, filename, time) -- add subdirs for new directories if isdir then