summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Assistant/Threads/TransferPoller.hs22
-rw-r--r--Assistant/Threads/TransferWatcher.hs20
-rw-r--r--Assistant/Threads/Watcher.hs2
-rw-r--r--Utility/DirWatcher.hs14
-rw-r--r--Utility/INotify.hs13
-rw-r--r--Utility/Types/DirWatcher.hs3
6 files changed, 63 insertions, 11 deletions
diff --git a/Assistant/Threads/TransferPoller.hs b/Assistant/Threads/TransferPoller.hs
index f8f9388f0..10ed7dd31 100644
--- a/Assistant/Threads/TransferPoller.hs
+++ b/Assistant/Threads/TransferPoller.hs
@@ -12,6 +12,7 @@ import Assistant.ThreadedMonad
import Assistant.DaemonStatus
import Logs.Transfer
import Utility.NotificationBroadcaster
+import qualified Assistant.Threads.TransferWatcher as TransferWatcher
import Control.Concurrent
import qualified Data.Map as M
@@ -42,9 +43,20 @@ transferPollerThread st dstatus = thread $ do
sz <- catchMaybeIO $
fromIntegral . fileSize
<$> getFileStatus f
- when (bytesComplete info /= sz && isJust sz) $
- alterTransferInfo dstatus t $
- \i -> i { bytesComplete = sz }
- {- Can't poll uploads, instead the upload code
- - updates the files. -}
+ newsize t info sz
+ {- Uploads don't need to be polled for when the
+ - TransferWatcher thread can track file
+ - modifications. -}
+ | TransferWatcher.watchesTransferSize = noop
+ {- Otherwise, this code polls the upload progress
+ - by reading the transfer info file. -}
+ | otherwise = do
+ let f = transferFile t g
+ mi <- catchDefaultIO Nothing $
+ readTransferInfoFile Nothing f
+ maybe noop (newsize t info . bytesComplete) mi
+ newsize t info sz
+ | bytesComplete info /= sz && isJust sz =
+ alterTransferInfo dstatus t $
+ \i -> i { bytesComplete = sz }
| otherwise = noop
diff --git a/Assistant/Threads/TransferWatcher.hs b/Assistant/Threads/TransferWatcher.hs
index ce0708a91..d4ff9176e 100644
--- a/Assistant/Threads/TransferWatcher.hs
+++ b/Assistant/Threads/TransferWatcher.hs
@@ -30,6 +30,7 @@ transferWatcherThread st dstatus transferqueue = thread $ do
let hooks = mkWatchHooks
{ addHook = hook onAdd
, delHook = hook onDel
+ , modifyHook = hook onModify
, errHook = hook onErr
}
void $ watchDir dir (const False) hooks id
@@ -71,6 +72,25 @@ onAdd st dstatus _ file _ = case parseTransferFile file of
{ transferRemote = r }
sameuuid t r = Remote.uuid r == transferUUID t
+{- Called when a transfer information file is updated.
+ -
+ - The only thing that should change in the transfer info is the
+ - bytesComplete, so that's the only thing updated in the DaemonStatus. -}
+onModify :: Handler
+onModify _ dstatus _ file _ = do
+ case parseTransferFile file of
+ Nothing -> noop
+ Just t -> go t =<< readTransferInfoFile Nothing file
+ where
+ go _ Nothing = noop
+ go t (Just newinfo) = alterTransferInfo dstatus t $ \info ->
+ info { bytesComplete = bytesComplete newinfo }
+
+{- This thread can only watch transfer sizes when the DirWatcher supports
+ - tracking modificatons to files. -}
+watchesTransferSize :: Bool
+watchesTransferSize = modifyTracked
+
{- Called when a transfer information file is removed. -}
onDel :: Handler
onDel st dstatus transferqueue file _ = case parseTransferFile file of
diff --git a/Assistant/Threads/Watcher.hs b/Assistant/Threads/Watcher.hs
index fa8b7b379..41396a23c 100644
--- a/Assistant/Threads/Watcher.hs
+++ b/Assistant/Threads/Watcher.hs
@@ -67,7 +67,7 @@ watchThread st dstatus transferqueue changechan = NamedThread thisThread $ do
where
startup = startupScan st dstatus
hook delay a = Just $ runHandler thisThread delay st dstatus transferqueue changechan a
- hooks delayadd = WatchHooks
+ hooks delayadd = mkWatchHooks
{ addHook = hook (Seconds <$> delayadd) onAdd
, delHook = hook Nothing onDel
, addSymlinkHook = hook Nothing onAddSymlink
diff --git a/Utility/DirWatcher.hs b/Utility/DirWatcher.hs
index 213aeb50a..e4ee83191 100644
--- a/Utility/DirWatcher.hs
+++ b/Utility/DirWatcher.hs
@@ -72,6 +72,20 @@ closingTracked = undefined
#endif
#endif
+/* With inotify, modifications to existing files can be tracked.
+ * Kqueue does not support this.
+ */
+modifyTracked :: Bool
+#if WITH_INOTIFY
+modifyTracked = True
+#else
+#if WITH_KQUEUE
+modifyTracked = False
+#else
+modifyTracked = undefined
+#endif
+#endif
+
/* Starts a watcher thread. The runStartup action is passed a scanner action
* to run, that will return once the initial directory scan is complete.
* Once runStartup returns, the watcher thread continues running,
diff --git a/Utility/INotify.hs b/Utility/INotify.hs
index 6af022819..7934c2446 100644
--- a/Utility/INotify.hs
+++ b/Utility/INotify.hs
@@ -38,9 +38,8 @@ import Control.Exception (throw)
- Note: Moving a file will cause events deleting it from its old location
- and adding it to the new location.
-
- - Note: Modification of files is not detected, and it's assumed that when
- - a file that was open for write is closed, it's finished being written
- - to, and can be added.
+ - Note: It's assumed that when a file that was open for write is closed,
+ - it's finished being written to, and can be added.
-
- Note: inotify has a limit to the number of watches allowed,
- /proc/sys/fs/inotify/max_user_watches (default 8192).
@@ -66,13 +65,16 @@ watchDir i dir ignored hooks
-- Select only inotify events required by the enabled
-- hooks, but always include Create so new directories can
-- be scanned.
- watchevents = Create : addevents ++ delevents
+ watchevents = Create : addevents ++ delevents ++ modifyevents
addevents
| hashook addHook || hashook addSymlinkHook = [MoveIn, CloseWrite]
| otherwise = []
delevents
| hashook delHook || hashook delDirHook = [MoveOut, Delete]
| otherwise = []
+ modifyevents
+ | hashook modifyHook = [Modify]
+ | otherwise = []
scan f = unless (ignored f) $ do
ms <- getstatus f
@@ -114,6 +116,9 @@ watchDir i dir ignored hooks
| otherwise = guarded $ runhook delHook f Nothing
where
guarded = unlessM (filetype (const True) f)
+ go (Modified { isDirectory = isd, maybeFilePath = Just f })
+ | isd = noop
+ | otherwise = runhook modifyHook f Nothing
go _ = noop
hashook h = isJust $ h hooks
diff --git a/Utility/Types/DirWatcher.hs b/Utility/Types/DirWatcher.hs
index ba7eae6a1..30ada9c68 100644
--- a/Utility/Types/DirWatcher.hs
+++ b/Utility/Types/DirWatcher.hs
@@ -19,7 +19,8 @@ data WatchHooks = WatchHooks
, delHook :: Hook FilePath
, delDirHook :: Hook FilePath
, errHook :: Hook String -- error message
+ , modifyHook :: Hook FilePath
}
mkWatchHooks :: WatchHooks
-mkWatchHooks = WatchHooks Nothing Nothing Nothing Nothing Nothing
+mkWatchHooks = WatchHooks Nothing Nothing Nothing Nothing Nothing Nothing