diff options
-rw-r--r-- | Presence/DNSCache.hs | 22 | ||||
-rw-r--r-- | src/Control/Concurrent/Lifted/Instrument.hs | 17 |
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 #-} | ||
13 | module DNSCache | 14 | module 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 | ||
23 | import Control.Concurrent | 24 | #ifdef THREAD_DEBUG |
25 | import Control.Concurrent.Lifted.Instrument | ||
26 | #else | ||
27 | import Control.Concurrent.Lifted | ||
28 | import GHC.Conc (labelThread) | ||
29 | #endif | ||
24 | import Control.Concurrent.STM | 30 | import Control.Concurrent.STM |
25 | import Data.Text ( Text ) | 31 | import Data.Text ( Text ) |
26 | import Network.Socket ( SockAddr(..), AddrInfoFlag(..), defaultHints, getAddrInfo, AddrInfo(..) ) | 32 | import Network.Socket ( SockAddr(..), AddrInfoFlag(..), defaultHints, getAddrInfo, AddrInfo(..) ) |
@@ -37,6 +43,8 @@ import Data.Function | |||
37 | import Data.List | 43 | import Data.List |
38 | import Data.Ord | 44 | import Data.Ord |
39 | import Data.Maybe | 45 | import Data.Maybe |
46 | import System.IO | ||
47 | import System.IO.Error | ||
40 | 48 | ||
41 | import SockAddr () | 49 | import SockAddr () |
42 | import ControlMaybe ( handleIO_ ) | 50 | import ControlMaybe ( handleIO_ ) |
@@ -95,6 +103,12 @@ make6mapped4 :: SockAddr -> SockAddr | |||
95 | make6mapped4 addr@(SockAddrInet6 {}) = addr | 103 | make6mapped4 addr@(SockAddrInet6 {}) = addr |
96 | make6mapped4 addr@(SockAddrInet port a) = SockAddrInet6 port 0 (0,0,0xFFFF,fromBE32 a) 0 | 104 | make6mapped4 addr@(SockAddrInet port a) = SockAddrInet6 port 0 (0,0,0xFFFF,fromBE32 a) 0 |
97 | 105 | ||
106 | tryForkOS :: IO () -> IO ThreadId | ||
107 | tryForkOS 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 :: | |||
107 | rawForwardResolve dns fail timeout addrtext = do | 121 | rawForwardResolve 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 | ||
138 | reportTimeout :: forall a. Show a => a -> IO () | 154 | reportTimeout :: forall a. Show a => a -> IO () |
139 | reportTimeout addrtext = do | 155 | reportTimeout addrtext = do |
140 | putStrLn $ "timeout resolving: "++show addrtext | 156 | hPutStrLn stderr $ "timeout resolving: "++show addrtext |
141 | -- killThread rt | 157 | -- killThread rt |
142 | 158 | ||
143 | timer :: forall t a. IO () -> Int -> TMVar [a] -> t -> IO () | 159 | timer :: 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 @@ | |||
2 | module Control.Concurrent.Lifted.Instrument | 2 | module 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 | ||
11 | import qualified Control.Concurrent.Lifted as Raw | 12 | import qualified Control.Concurrent.Lifted as Raw |
12 | import Control.Concurrent.Lifted hiding (fork) | 13 | import Control.Concurrent.Lifted hiding (fork,forkOS) |
13 | import Control.Exception (fromException) | 14 | import Control.Exception (fromException) |
14 | import Control.Monad.Trans.Control | 15 | import Control.Monad.Trans.Control |
15 | import System.IO.Unsafe | 16 | import System.IO.Unsafe |
@@ -46,9 +47,19 @@ forkIO :: IO () -> IO ThreadId | |||
46 | forkIO = fork | 47 | forkIO = fork |
47 | {-# INLINE forkIO #-} | 48 | {-# INLINE forkIO #-} |
48 | 49 | ||
50 | forkOS :: (MonadBaseControl IO m, MonadIO m) => m () -> m ThreadId | ||
51 | forkOS = instrumented Raw.forkOS | ||
52 | {-# INLINE forkOS #-} | ||
53 | |||
49 | fork :: (MonadBaseControl IO m, MonadIO m) => m () -> m ThreadId | 54 | fork :: (MonadBaseControl IO m, MonadIO m) => m () -> m ThreadId |
50 | fork action = do | 55 | fork = instrumented Raw.fork |
51 | t <- Raw.fork $ do | 56 | {-# INLINE fork #-} |
57 | |||
58 | instrumented :: ( MonadBaseControl IO m | ||
59 | , MonadIO m) => | ||
60 | (m () -> m ThreadId) -> m () -> m ThreadId | ||
61 | instrumented 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)) |