summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Presence/DNSCache.hs22
-rw-r--r--src/Control/Concurrent/Lifted/Instrument.hs17
2 files changed, 33 insertions, 6 deletions
diff --git a/Presence/DNSCache.hs b/Presence/DNSCache.hs
index 4a936d57..82e0cb56 100644
--- a/Presence/DNSCache.hs
+++ b/Presence/DNSCache.hs
@@ -10,6 +10,7 @@
10-- this. 10-- this.
11{-# LANGUAGE TupleSections #-} 11{-# LANGUAGE TupleSections #-}
12{-# LANGUAGE RankNTypes #-} 12{-# LANGUAGE RankNTypes #-}
13{-# LANGUAGE CPP #-}
13module DNSCache 14module DNSCache
14 ( DNSCache 15 ( DNSCache
15 , reverseResolve 16 , reverseResolve
@@ -20,7 +21,12 @@ module DNSCache
20 , withPort 21 , withPort
21 ) where 22 ) where
22 23
23import Control.Concurrent 24#ifdef THREAD_DEBUG
25import Control.Concurrent.Lifted.Instrument
26#else
27import Control.Concurrent.Lifted
28import GHC.Conc (labelThread)
29#endif
24import Control.Concurrent.STM 30import Control.Concurrent.STM
25import Data.Text ( Text ) 31import Data.Text ( Text )
26import Network.Socket ( SockAddr(..), AddrInfoFlag(..), defaultHints, getAddrInfo, AddrInfo(..) ) 32import Network.Socket ( SockAddr(..), AddrInfoFlag(..), defaultHints, getAddrInfo, AddrInfo(..) )
@@ -37,6 +43,8 @@ import Data.Function
37import Data.List 43import Data.List
38import Data.Ord 44import Data.Ord
39import Data.Maybe 45import Data.Maybe
46import System.IO
47import System.IO.Error
40 48
41import SockAddr () 49import SockAddr ()
42import ControlMaybe ( handleIO_ ) 50import ControlMaybe ( handleIO_ )
@@ -95,6 +103,12 @@ make6mapped4 :: SockAddr -> SockAddr
95make6mapped4 addr@(SockAddrInet6 {}) = addr 103make6mapped4 addr@(SockAddrInet6 {}) = addr
96make6mapped4 addr@(SockAddrInet port a) = SockAddrInet6 port 0 (0,0,0xFFFF,fromBE32 a) 0 104make6mapped4 addr@(SockAddrInet port a) = SockAddrInet6 port 0 (0,0,0xFFFF,fromBE32 a) 0
97 105
106tryForkOS :: IO () -> IO ThreadId
107tryForkOS action = catchIOError (forkOS action) $ \e -> do
108 hPutStrLn stderr $ "DNSCache: Link with -threaded to avoid excessively long time-out."
109 forkIO action
110
111
98-- Attempt to resolve the given domain name. Returns an empty list if the 112-- Attempt to resolve the given domain name. Returns an empty list if the
99-- resolve operation takes longer than the timeout, but the 'DNSCache' will be 113-- resolve operation takes longer than the timeout, but the 'DNSCache' will be
100-- updated when the resolve completes. 114-- updated when the resolve completes.
@@ -107,7 +121,9 @@ rawForwardResolve ::
107rawForwardResolve dns fail timeout addrtext = do 121rawForwardResolve dns fail timeout addrtext = do
108 r <- atomically newEmptyTMVar 122 r <- atomically newEmptyTMVar
109 mvar <- atomically newEmptyTMVar 123 mvar <- atomically newEmptyTMVar
110 rt <- forkOS $ resolver r mvar 124 rt <- tryForkOS $ do
125 myThreadId >>= flip labelThread ("resolve."++show addrtext)
126 resolver r mvar
111 -- TODO: System.Timeout.timeout might be more appropriate than this 127 -- TODO: System.Timeout.timeout might be more appropriate than this
112 -- hack involving throwTo (ErrorCall "Interrupteddelay"). 128 -- hack involving throwTo (ErrorCall "Interrupteddelay").
113 tt <- forkIO $ timer (fail addrtext) timeout r rt 129 tt <- forkIO $ timer (fail addrtext) timeout r rt
@@ -137,7 +153,7 @@ strip_brackets s =
137 153
138reportTimeout :: forall a. Show a => a -> IO () 154reportTimeout :: forall a. Show a => a -> IO ()
139reportTimeout addrtext = do 155reportTimeout addrtext = do
140 putStrLn $ "timeout resolving: "++show addrtext 156 hPutStrLn stderr $ "timeout resolving: "++show addrtext
141 -- killThread rt 157 -- killThread rt
142 158
143timer :: forall t a. IO () -> Int -> TMVar [a] -> t -> IO () 159timer :: forall t a. IO () -> Int -> TMVar [a] -> t -> IO ()
diff --git a/src/Control/Concurrent/Lifted/Instrument.hs b/src/Control/Concurrent/Lifted/Instrument.hs
index 7e4a7356..41814d98 100644
--- a/src/Control/Concurrent/Lifted/Instrument.hs
+++ b/src/Control/Concurrent/Lifted/Instrument.hs
@@ -2,6 +2,7 @@
2module Control.Concurrent.Lifted.Instrument 2module Control.Concurrent.Lifted.Instrument
3 ( module Control.Concurrent.Lifted 3 ( module Control.Concurrent.Lifted
4 , forkIO 4 , forkIO
5 , forkOS
5 , fork 6 , fork
6 , labelThread 7 , labelThread
7 , threadsInformation 8 , threadsInformation
@@ -9,7 +10,7 @@ module Control.Concurrent.Lifted.Instrument
9 ) where 10 ) where
10 11
11import qualified Control.Concurrent.Lifted as Raw 12import qualified Control.Concurrent.Lifted as Raw
12import Control.Concurrent.Lifted hiding (fork) 13import Control.Concurrent.Lifted hiding (fork,forkOS)
13import Control.Exception (fromException) 14import Control.Exception (fromException)
14import Control.Monad.Trans.Control 15import Control.Monad.Trans.Control
15import System.IO.Unsafe 16import System.IO.Unsafe
@@ -46,9 +47,19 @@ forkIO :: IO () -> IO ThreadId
46forkIO = fork 47forkIO = fork
47{-# INLINE forkIO #-} 48{-# INLINE forkIO #-}
48 49
50forkOS :: (MonadBaseControl IO m, MonadIO m) => m () -> m ThreadId
51forkOS = instrumented Raw.forkOS
52{-# INLINE forkOS #-}
53
49fork :: (MonadBaseControl IO m, MonadIO m) => m () -> m ThreadId 54fork :: (MonadBaseControl IO m, MonadIO m) => m () -> m ThreadId
50fork action = do 55fork = instrumented Raw.fork
51 t <- Raw.fork $ do 56{-# INLINE fork #-}
57
58instrumented :: ( MonadBaseControl IO m
59 , MonadIO m) =>
60 (m () -> m ThreadId) -> m () -> m ThreadId
61instrumented rawFork action = do
62 t <- rawFork $ do
52 tid <- myThreadId 63 tid <- myThreadId
53 tm <- liftBase getCurrentTime 64 tm <- liftBase getCurrentTime
54 bracket_ (modifyThreads $! Map.insert tid (PerThread "" tm)) 65 bracket_ (modifyThreads $! Map.insert tid (PerThread "" tm))