only use dbus when there's a client connected we know will send mount events
This commit is contained in:
parent
0496a3971d
commit
6b4fe507f6
1 changed files with 44 additions and 22 deletions
|
@ -21,6 +21,7 @@ import qualified Data.Set as S
|
|||
|
||||
#if WITH_DBUS
|
||||
import DBus.Client
|
||||
import DBus
|
||||
#else
|
||||
#warning Building without dbus support; will use mtab polling
|
||||
#endif
|
||||
|
@ -34,30 +35,51 @@ mountWatcherThread st handle =
|
|||
#endif
|
||||
|
||||
#if WITH_DBUS
|
||||
|
||||
dbusThread :: ThreadState -> DaemonStatusHandle -> IO ()
|
||||
dbusThread st handle = do
|
||||
r <- tryIO connectSession
|
||||
case r of
|
||||
Left e -> do
|
||||
print $ "Failed to connect to dbus; falling back to mtab polling (" ++ show e ++ ")"
|
||||
pollingThread st handle
|
||||
Right client -> do
|
||||
{- Store the current mount points in an mvar,
|
||||
- to be compared later. We could in theory work
|
||||
- out the mount point from the dbus message, but
|
||||
- this is easier. -}
|
||||
mvar <- newMVar =<< currentMountPoints
|
||||
-- Spawn a listener thread, and returns.
|
||||
listen client mountadded (go mvar)
|
||||
dbusThread st handle = (go =<< connectSession) `catchIO` onerr
|
||||
where
|
||||
mountadded = matchAny
|
||||
{ matchInterface = Just "org.gtk.Private.RemoteVolumeMonitor"
|
||||
, matchMember = Just "MountAdded"
|
||||
}
|
||||
go mvar event = do
|
||||
nowmounted <- currentMountPoints
|
||||
wasmounted <- swapMVar mvar nowmounted
|
||||
handleMounts st handle wasmounted nowmounted
|
||||
go client = ifM (checkMountMonitor client)
|
||||
( do
|
||||
{- Store the current mount points in an mvar,
|
||||
- to be compared later. We could in theory
|
||||
- work out the mount point from the dbus
|
||||
- message, but this is easier. -}
|
||||
mvar <- newMVar =<< currentMountPoints
|
||||
listen client mountAdded $ \_event -> do
|
||||
nowmounted <- currentMountPoints
|
||||
wasmounted <- swapMVar mvar nowmounted
|
||||
handleMounts st handle wasmounted nowmounted
|
||||
, do
|
||||
runThreadState st $
|
||||
warning "No known volume monitor available through dbus; falling back to mtab polling"
|
||||
pollinstead
|
||||
)
|
||||
onerr e = do
|
||||
runThreadState st $
|
||||
warning $ "Failed to use dbus; falling back to mtab polling (" ++ show e ++ ")"
|
||||
pollinstead
|
||||
pollinstead = pollingThread st handle
|
||||
|
||||
listClientNames :: Client -> IO [String]
|
||||
listClientNames client = do
|
||||
reply <- call_ client (methodCall "/org/freedesktop/DBus" "org.freedesktop.DBus" "ListNames")
|
||||
{ methodCallDestination = Just "org.freedesktop.DBus" }
|
||||
return $ fromMaybe [] $ fromVariant (methodReturnBody reply !! 0)
|
||||
|
||||
{- Examine the list of clients connected to dbus, to see if there
|
||||
- are any we can use to monitor mounts. -}
|
||||
checkMountMonitor :: Client -> IO Bool
|
||||
checkMountMonitor client = any (`elem` knownclients) <$> listClientNames client
|
||||
where
|
||||
knownclients = ["org.gtk.Private.GduVolumeMonitor"]
|
||||
|
||||
{- Filter matching events recieved when drives are mounted. -}
|
||||
mountAdded ::MatchRule
|
||||
mountAdded = matchAny
|
||||
{ matchInterface = Just "org.gtk.Private.RemoteVolumeMonitor"
|
||||
, matchMember = Just "MountAdded"
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue