diff --git a/core/feature.h b/core/feature.h index 5f72065..2ebd4a7 100644 --- a/core/feature.h +++ b/core/feature.h @@ -13,6 +13,7 @@ #include "config.h" // some older machines need this to see pselect +#define _BSD_SOURCE 1 #define _DEFAULT_SOURCE 1 #define _XOPEN_SOURCE 700 #define _DARWIN_C_SOURCE 1 diff --git a/core/observe.c b/core/observe.c index df1df25..64e5aeb 100644 --- a/core/observe.c +++ b/core/observe.c @@ -8,6 +8,7 @@ */ #include "feature.h" +#include #include #include #include diff --git a/core/signal.c b/core/signal.c index 8cab0cd..9466a51 100644 --- a/core/signal.c +++ b/core/signal.c @@ -271,5 +271,12 @@ signal_notify( if( lua_pcall( L, 1, 0, -3 ) ) exit( -1 ); lua_pop( L, 1 ); + + if( lua_gettop( L ) ) + { + logstring( "Error", "internal, stack is dirty." ); + l_stackdump( L ); + exit( -1 ); + } } diff --git a/default/signal.lua b/default/signal.lua index 70835ce..a3a8583 100644 --- a/default/signal.lua +++ b/default/signal.lua @@ -14,6 +14,17 @@ if not default then error( 'default not loaded' ) end default.signal = { } +-- +-- +-- +local function onCollect +( + sync -- the user intf to the sync a child finished for +) + +end + + local function sighup ( ) print( 'GOT A HUP SIGNAL' ) @@ -26,12 +37,18 @@ local function sigint ( ) print( 'GOT AN INT SIGNAL' ) - for _, s in ipairs( syncs ) + for _, sync in ipairs( syncs ) do - print( 'a sync' ) - end + sync.stop( ) - os.exit( 1 ) + if( #sync.pids == 0 ) + then + syncs.remove( sync ) + else + sync.onCollect( onCollect ) + end + end +-- os.exit( 1 ) end @@ -55,6 +72,8 @@ init = local int = getsignal( 'INT' ) local term = getsignal( 'TERM' ) + print( 'INIT', hup, int, term ) + if hup ~= false then hup = sighup end if int ~= false then int = sigint end if term ~= false then term = sigterm end @@ -62,6 +81,6 @@ init = onsignal( 'HUP', hup, 'INT', int, - 'TERM', iterm + 'TERM', term ) end diff --git a/mantle/signal.lua b/mantle/signal.lua index 0bdf15b..c841145 100644 --- a/mantle/signal.lua +++ b/mantle/signal.lua @@ -95,7 +95,7 @@ function onsignal if n % 2 ~= 0 then - error( 'onsignal with uneven number of arguments called', 2 ) + error( 'onsignal() with uneven number of arguments called', 2 ) end for a = 1, n, 2 diff --git a/mantle/sync.lua b/mantle/sync.lua index fda5845..1a3c5aa 100644 --- a/mantle/sync.lua +++ b/mantle/sync.lua @@ -204,6 +204,14 @@ local function collect end self.processes[ pid ] = nil + + if self.onCollect + then + for _, func in ipairs( self.onCollect ) + do + func( self:getUserIntf( ) ) + end + end end @@ -469,7 +477,8 @@ local function getAlarm ( self ) - if #self.processes >= self.config.maxProcesses + if self.stopped + or #self.processes >= self.config.maxProcesses then return false end @@ -557,7 +566,8 @@ local function invokeActions ) log( 'Function', 'invokeActions( "', self.config.name, '", ', timestamp, ' )' ) - if #self.processes >= self.config.maxProcesses + if self.stopped + or #self.processes >= self.config.maxProcesses then -- no new processes return @@ -731,13 +741,48 @@ local function getUserIntf if ui then return ui end - ui = { muhkuh = true } + ui = { + -- Stops the sync, meaning no more + -- processes will be spawned + stop = function( ) + self.stopped = true + end, + + -- Registers an additional function to be called + -- after each collect. + -- + -- Used by default signal handlers to wait + -- for children to finish (or react on forwarded signal) + onCollect = function( func ) + if not self.onCollect + then + self.onCollect = { func } + else + table.insert( self.onCollect, func ) + end + end, + + -- Returns a list of pids of children + -- processes + pids = function + ( ) + local pids = { } + + for k, v in pairs( self.processes ) + do + pids[ k ] = v + end + + return pids + end, + } self.userIntf = ui return ui end + -- -- Creates a new Sync. -- @@ -748,11 +793,12 @@ local function new local s = { -- fields - config = config, - delays = Queue.new( ), - source = config.source, + config = config, + delays = Queue.new( ), + source = config.source, processes = Counter.new( ), - filters = nil, + filters = nil, + stopped = false, -- functions addBlanketDelay = addBlanketDelay, @@ -765,11 +811,13 @@ local function new getAlarm = getAlarm, getDelays = getDelays, getNextDelay = getNextDelay, - getUserIntf = getUserIntf, invokeActions = invokeActions, removeDelay = removeDelay, rmExclude = rmExclude, statusReport = statusReport, + + -- use interface + getUserIntf = getUserIntf, } s.inlet = InletFactory.newInlet( s ) diff --git a/mantle/syncmaster.lua b/mantle/syncmaster.lua index e0fe53a..c1d71e2 100644 --- a/mantle/syncmaster.lua +++ b/mantle/syncmaster.lua @@ -77,7 +77,7 @@ end -- local function get ( i ) - return syncList[ i ]; + return syncList[ i ] end -- diff --git a/mantle/user.lua b/mantle/user.lua index 510d7fd..8224ffe 100644 --- a/mantle/user.lua +++ b/mantle/user.lua @@ -266,23 +266,38 @@ user.syncs = -- iterator for user syncs function iter ( - self, - pos + self, -- the syncs list copy + pos -- position ) pos = pos + 1 - if pos >= #SyncMaster then return nil end + local result = self[ pos ] - local sync = SyncMaster.get( pos ) + if result == nil then return nil end - return pos, sync:getUserIntf( ) + return pos, self[ pos ] end local mt = { } + -- + -- This iterator will make a copy of the syncs at the moment + -- it is started, so the list can be manipulated while a loop + -- iterates through the copy. + -- mt.__ipairs = - function( self ) - return iter, self, -1 + function + ( + self -- is user.syncs + ) + local list = { } + + for k = 0, #SyncMaster - 1 + do + list[ k ] = SyncMaster.get( k ):getUserIntf( ) + end + + return iter, list, -1 end -- public interface