
Hi, for a program of mine (darcswatch[1]), a rather long running process is run at certain events (by cron, and by new emails). I want to achieve that: * Only one instance of the program runs at a time. * If new events come in while the program runs, it should re-run itself * There is information attached to the events (only one Bool ATM) So I’d like to implement something with this, or a similar, interface: ======================================================================= module MyLocking where -- | tries to get the lock. If it fails, notifies the running process -- to re-start itself afterwards, with the given information -- returns True if the lock was aquired lockOrMark :: Show a => FilePath -> a -> IO Bool -- | release the lock. If new events have come in, they are returned -- in the list, and the lock is still kept. If the list is empty, -- the lock was successfully released. releaseLock :: Read a => FilePath -> IO [a] ======================================================================= I would use this module in this way: realWork args = do someStuff args newArgs <- releaseLock "someDir/" unless (null newArgs) $ do -- we missed some events, so re-run and then try again. let newArg = combineInSomeWay newArgs realWork newArg main = do args <- getArgs l <- lockOrMark "someDir/" args when l $ do -- we got the lock, so lets work realWork args I hope this makes the idea clear. How could a possible implementation look like, when all operations should be atomic? I was considering this, would it work fine? lockOrMark would try to create a directory in the path. Whoever creates the directory has the lock. If it works, create. If it fails, because the directory already exists, then write the given args to a temporary file with a unique name, and move it into that directory. If that fails (because the directory has disappeared, i.e. the lock released), start over with trying to create the directory. If it works, then you are done. releaseLock would try to rmdir the directory. If that succeeds, no files have been in there, so no events were missed. If it does not succeed, then there were files. Read and delete them and return the list of arguments contained in them. Greetings, Joachim [1] http://darcswatch.nomeata.de/ -- Joachim Breitner e-Mail: mail@joachim-breitner.de Homepage: http://www.joachim-breitner.de ICQ#: 74513189 Jabber-ID: nomeata@joachim-breitner.de