summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Assistant/Threads/MountWatcher.hs5
-rw-r--r--Assistant/Threads/NetWatcher.hs17
-rw-r--r--Utility/DBus.hs16
-rw-r--r--debian/changelog1
-rw-r--r--debian/control2
-rw-r--r--git-annex.cabal2
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)