summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjim@bo <jim@bo>2018-06-22 02:42:16 -0400
committerjim@bo <jim@bo>2018-06-22 02:45:15 -0400
commita4af87c425950ff6697a67ae5acb7abd2108580f (patch)
tree6034d0354558bbce9d81d853103567b704b50de0 /src
parentbabb35615121227e0ad2123d211fd138b6fe55c0 (diff)
Avoid MVar access in dput & dtrace
Diffstat (limited to 'src')
-rw-r--r--src/DPut.hs23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/DPut.hs b/src/DPut.hs
index 94a237f8..73d142b7 100644
--- a/src/DPut.hs
+++ b/src/DPut.hs
@@ -3,13 +3,15 @@ module DPut where
3import Control.Monad.IO.Class 3import Control.Monad.IO.Class
4import Control.Concurrent.STM 4import Control.Concurrent.STM
5import qualified Data.Map.Strict as Map 5import qualified Data.Map.Strict as Map
6import System.IO (stderr,hPutStrLn)
7import Data.Maybe 6import Data.Maybe
7import Data.IORef
8import System.IO (stderr,hPutStrLn)
8import System.IO.Unsafe (unsafePerformIO) 9import System.IO.Unsafe (unsafePerformIO)
9import System.Log.Logger 10import System.Log.Logger
10import qualified Data.ByteString.Char8 as B 11import qualified Data.ByteString.Char8 as B
11import qualified Data.Text as T 12import qualified Data.Text as T
12import qualified Data.Text.Encoding as T 13import qualified Data.Text.Encoding as T
14import Debug.Trace
13 15
14-- | Debug Tags, add more as needed, but ensure XAnnounce is always first, XMisc last 16-- | Debug Tags, add more as needed, but ensure XAnnounce is always first, XMisc last
15data DebugTag 17data DebugTag
@@ -41,16 +43,29 @@ dput tag msg = liftIO $ debugM (appName <.> show tag) msg
41dputB :: MonadIO m => DebugTag -> B.ByteString -> m () 43dputB :: MonadIO m => DebugTag -> B.ByteString -> m ()
42dputB tag msg = liftIO $ debugM (appName <.> show tag) (T.unpack . T.decodeUtf8 $ msg) 44dputB tag msg = liftIO $ debugM (appName <.> show tag) (T.unpack . T.decodeUtf8 $ msg)
43 45
46{-# NOINLINE verbosityMap #-}
47verbosityMap :: IORef (Map.Map DebugTag Bool)
48verbosityMap = unsafePerformIO $ newIORef (Map.empty)
49
44-- | Trace version of 'dput' works in arbitrary monad, using unsafePerformIO. 50-- | Trace version of 'dput' works in arbitrary monad, using unsafePerformIO.
45tput :: Applicative m => DebugTag -> String -> m () 51tput :: Applicative m => DebugTag -> String -> m ()
46tput tag msg = (unsafePerformIO $ dput tag msg) `seq` pure () 52tput tag msg =
53 let mp = unsafePerformIO $ readIORef verbosityMap
54 in if fromMaybe True (Map.lookup tag mp)
55 then trace msg (pure ())
56 else pure ()
47 57
48-- | like 'trace' but parameterized with 'DebugTag' 58-- | like 'trace' but parameterized with 'DebugTag'
49dtrace :: DebugTag -> String -> a -> a 59dtrace :: DebugTag -> String -> a -> a
50dtrace tag msg result = (unsafePerformIO $ dput tag msg) `seq` result 60dtrace tag msg result = let mp = unsafePerformIO $ readIORef verbosityMap
61 in if fromMaybe True (Map.lookup tag mp)
62 then trace msg result
63 else result
51 64
52setTagLevel :: Priority -> DebugTag -> IO () 65setTagLevel :: Priority -> DebugTag -> IO ()
53setTagLevel level tag = updateGlobalLogger (appName <.> show tag) (setLevel level) 66setTagLevel level tag = do
67 updateGlobalLogger (appName <.> show tag) (setLevel level)
68 modifyIORef verbosityMap (Map.insert tag (level <= DEBUG))
54 69
55setQuiet :: DebugTag -> IO () 70setQuiet :: DebugTag -> IO ()
56setQuiet = setTagLevel WARNING 71setQuiet = setTagLevel WARNING