diff options
-rw-r--r-- | Assistant/Threads/MountWatcher.hs | 5 | ||||
-rw-r--r-- | Assistant/Threads/NetWatcher.hs | 17 | ||||
-rw-r--r-- | Utility/DBus.hs | 16 | ||||
-rw-r--r-- | debian/changelog | 1 | ||||
-rw-r--r-- | debian/control | 2 | ||||
-rw-r--r-- | git-annex.cabal | 2 |
6 files changed, 25 insertions, 18 deletions
diff --git a/Assistant/Threads/MountWatcher.hs b/Assistant/Threads/MountWatcher.hs index 294f9a972..a5200adfe 100644 --- a/Assistant/Threads/MountWatcher.hs +++ b/Assistant/Threads/MountWatcher.hs @@ -72,6 +72,11 @@ dbusThread st dstatus scanremotes = E.catch (runClient getSessionAddress go) one ) onerr :: E.SomeException -> IO () onerr e = do + {- If the session dbus fails, the user probably + - logged out of their desktop. Even if they log + - back in, we won't have access to the dbus + - session key, so polling is the best that can be + - done in this situation. -} runThreadState st $ warning $ "dbus failed; falling back to mtab polling (" ++ show e ++ ")" pollinstead diff --git a/Assistant/Threads/NetWatcher.hs b/Assistant/Threads/NetWatcher.hs index f9ca5641d..96b8007cc 100644 --- a/Assistant/Threads/NetWatcher.hs +++ b/Assistant/Threads/NetWatcher.hs @@ -24,7 +24,6 @@ import Utility.DBus import DBus.Client import DBus import Data.Word (Word32) -import qualified Control.Exception as E #else #warning Building without dbus support; will poll for network connection changes #endif @@ -57,22 +56,24 @@ netWatcherFallbackThread st dstatus scanremotes = thread $ #if WITH_DBUS dbusThread :: ThreadState -> DaemonStatusHandle -> ScanRemoteMap -> IO () -dbusThread st dstatus scanremotes = E.catch (runClient getSystemAddress go) onerr +dbusThread st dstatus scanremotes = persistentClient getSystemAddress () onerr go where go client = ifM (checkNetMonitor client) ( do - listenNMConnections client handle - listenWicdConnections client handle + listenNMConnections client handleconn + listenWicdConnections client handleconn , do runThreadState st $ warning "No known network monitor available through dbus; falling back to polling" ) - onerr :: E.SomeException -> IO () - onerr e = runThreadState st $ - warning $ "dbus failed; falling back to polling (" ++ show e ++ ")" - handle = do + handleconn = do debug thisThread ["detected network connection"] handleConnection st dstatus scanremotes + onerr e _ = do + runThreadState st $ + warning $ "lost dbus connection; falling back to polling (" ++ show e ++ ")" + {- Wait, in hope that dbus will come back -} + threadDelaySeconds (Seconds 60) {- Examine the list of services connected to dbus, to see if there - are any we can use to monitor network connections. -} diff --git a/Utility/DBus.hs b/Utility/DBus.hs index 3b34e00ac..a1a4c4804 100644 --- a/Utility/DBus.hs +++ b/Utility/DBus.hs @@ -5,7 +5,7 @@ - Licensed under the GNU GPL version 3 or higher. -} -{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-} module Utility.DBus where @@ -65,15 +65,15 @@ runClient getaddr clientaction = do - If the connection is lost, runs onretry, which can do something like - a delay, or printing a warning, and has a state value (useful for - exponential backoff). Once onretry returns, the connection is retried. - - - - Warning: Currently connectWith can throw a SocketError and leave behind - - an open FD. So each retry leaks one FD. -} + -} persistentClient :: IO (Maybe Address) -> v -> (SomeException -> v -> IO v) -> (Client -> IO ()) -> IO () -persistentClient getaddr v onretry clientaction = do +persistentClient getaddr v onretry clientaction = {- runClient can fail with not just ClientError, but also other - - things, if dbus is not running. -} - r <- E.try (runClient getaddr clientaction) :: IO (Either SomeException ()) - either retry return r + - things, if dbus is not running. Let async exceptions through. -} + runClient getaddr clientaction `E.catches` + [ Handler (\ (e :: AsyncException) -> E.throw e) + , Handler (\ (e :: SomeException) -> retry e) + ] where retry e = do v' <- onretry e v diff --git a/debian/changelog b/debian/changelog index aa3eb9db5..36bba7c49 100644 --- a/debian/changelog +++ b/debian/changelog @@ -24,6 +24,7 @@ git-annex (3.20121018) UNRELEASED; urgency=low * configure: Check that checksum programs produce correct checksums. * Re-enable dbus, using a new version of the library that fixes the memory leak. + * NetWatcher: When dbus connection is lost, try to reconnect. * Use USER and HOME environment when set, and only fall back to getpwent, which doesn't work with LDAP or NIS. diff --git a/debian/control b/debian/control index ec648288a..ba8f571c8 100644 --- a/debian/control +++ b/debian/control @@ -22,7 +22,7 @@ Build-Depends: libghc-edit-distance-dev, libghc-hinotify-dev [linux-any], libghc-stm-dev (>= 2.3), - libghc-dbus-dev [linux-any] (>= 0.10.2), + libghc-dbus-dev [linux-any] (>= 0.10.3), libghc-yesod-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64], libghc-yesod-static-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64], libghc-yesod-default-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64], diff --git a/git-annex.cabal b/git-annex.cabal index 90620f4b3..5b7e78654 100644 --- a/git-annex.cabal +++ b/git-annex.cabal @@ -77,7 +77,7 @@ Executable git-annex C-Sources: Utility/libkqueue.c if os(linux) && flag(Dbus) - Build-Depends: dbus (>= 0.10.2) + Build-Depends: dbus (>= 0.10.3) CPP-Options: -DWITH_DBUS if flag(Webapp) && flag(Assistant) |