diff options
author | Joey Hess <joey@kitenet.net> | 2012-06-18 13:01:58 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2012-06-18 13:01:58 -0400 |
commit | a39b73d118c18707e6549d57a902fca9966119f8 (patch) | |
tree | 8778c4a6bb3d6bb73f4be34668aae0f864c8e725 | |
parent | dc3d9d1e982f7342dd3e2b3fc14fbbe85e7acd3e (diff) |
recurse dirTree and open the directories for kqueue to watch
-rw-r--r-- | Assistant/Watcher.hs | 22 | ||||
-rw-r--r-- | Utility/Kqueue.hs | 23 |
2 files changed, 31 insertions, 14 deletions
diff --git a/Assistant/Watcher.hs b/Assistant/Watcher.hs index 7c913d98c..52c3780ab 100644 --- a/Assistant/Watcher.hs +++ b/Assistant/Watcher.hs @@ -37,8 +37,6 @@ import System.INotify import Utility.Kqueue #endif -type Handler = FilePath -> Maybe FileStatus -> DaemonStatusHandle -> Annex (Maybe Change) - checkCanWatch :: Annex () checkCanWatch = do #if (WITH_INOTIFY || WITH_KQUEUE) @@ -66,7 +64,7 @@ watchThread st dstatus changechan = withINotify $ \i -> do showAction "scanning" -- This does not return until the startup scan is done. -- That can take some time for large trees. - watchDir i "." (ignored . takeFileName) hooks + watchDir i "." ignored hooks runThreadState st $ modifyDaemonStatus dstatus $ \s -> s { scanComplete = True } -- Notice any files that were deleted before inotify @@ -86,18 +84,24 @@ watchThread st dstatus changechan = withINotify $ \i -> do } #else #ifdef WITH_KQUEUE -watchThread st dstatus changechan = do - print =<< waitChange [stdError, stdOutput] +watchThread st dstatus changechan = forever $ do + dirs <- scanRecursive "." ignored + changeddir <- waitChange dirs + print $ "detected a change in " ++ show changeddir #else watchThread = undefined #endif /* WITH_KQUEUE */ #endif /* WITH_INOTIFY */ ignored :: FilePath -> Bool -ignored ".git" = True -ignored ".gitignore" = True -ignored ".gitattributes" = True -ignored _ = False +ignored = ig . takeFileName + where + ig ".git" = True + ig ".gitignore" = True + ig ".gitattributes" = True + ig _ = False + +type Handler = FilePath -> Maybe FileStatus -> DaemonStatusHandle -> Annex (Maybe Change) {- Runs an action handler, inside the Annex monad, and if there was a - change, adds it to the ChangeChan. diff --git a/Utility/Kqueue.hs b/Utility/Kqueue.hs index bfc6ee9fc..aabea7d03 100644 --- a/Utility/Kqueue.hs +++ b/Utility/Kqueue.hs @@ -7,7 +7,10 @@ {-# LANGUAGE ForeignFunctionInterface #-} -module Utility.Kqueue ( waitChange ) where +module Utility.Kqueue ( + waitChange, + scanRecursive +) where import Common @@ -16,16 +19,26 @@ import Foreign.C.Types import Foreign.C.Error import Foreign.Ptr import Foreign.Marshal +import qualified Data.Map as M + +type DirMap = M.Map Fd FilePath foreign import ccall unsafe "libkqueue.h waitchange" c_waitchange :: Ptr Fd -> IO Fd -waitChange :: [Fd] -> IO (Maybe Fd) -waitChange fds = withArray fds $ \c_fds -> do - ret <- c_waitchange c_fds +waitChange :: DirMap -> IO (Maybe FilePath) +waitChange dirmap = withArray (M.keys dirmap) $ \c_fds -> do + changed <- c_waitchange c_fds ifM (safeErrno <$> getErrno) - ( return $ Just ret + ( return $ M.lookup changed dirmap , return Nothing ) where safeErrno (Errno v) = v == 0 + +scanRecursive :: FilePath -> (FilePath -> Bool) -> IO DirMap +scanRecursive dir prune = M.fromList <$> (mapM opendir =<< dirTree dir prune) + where + opendir d = (,) + <$> openFd d ReadOnly Nothing defaultFileFlags + <*> pure d |