summaryrefslogtreecommitdiff
path: root/lifted-concurrent
diff options
context:
space:
mode:
authorJames Crayne <jim.crayne@gmail.com>2019-09-28 13:43:29 -0400
committerJoe Crayne <joe@jerkface.net>2020-01-01 19:27:53 -0500
commit11987749fc6e6d3e53ea737d46d5ab13a16faeb8 (patch)
tree5716463275c2d3e902889db619908ded2a73971c /lifted-concurrent
parentadd2c76bced51fde5e9917e7449ef52be70faf87 (diff)
Factor out some new libraries
word64-map: Data.Word64Map network-addr: Network.Address tox-crypto: Crypto.Tox lifted-concurrent: Control.Concurrent.Lifted.Instrument Control.Concurrent.Async.Lifted.Instrument psq-wrap: Data.Wrapper.PSQInt Data.Wrapper.PSQ minmax-psq: Data.MinMaxPSQ tasks: Control.Concurrent.Tasks kad: Network.Kademlia Network.Kademlia.Bootstrap Network.Kademlia.Routing Network.Kademlia.CommonAPI Network.Kademlia.Persistence Network.Kademlia.Search
Diffstat (limited to 'lifted-concurrent')
-rw-r--r--lifted-concurrent/CHANGELOG.md5
-rw-r--r--lifted-concurrent/LICENSE30
-rw-r--r--lifted-concurrent/Setup.hs2
-rw-r--r--lifted-concurrent/lifted-concurrent.cabal34
-rw-r--r--lifted-concurrent/src/Control/Concurrent/Async/Lifted/Instrument.hs5
-rw-r--r--lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs98
-rw-r--r--lifted-concurrent/src/DebugTag.hs24
7 files changed, 198 insertions, 0 deletions
diff --git a/lifted-concurrent/CHANGELOG.md b/lifted-concurrent/CHANGELOG.md
new file mode 100644
index 00000000..3915e1ca
--- /dev/null
+++ b/lifted-concurrent/CHANGELOG.md
@@ -0,0 +1,5 @@
1# Revision history for lifted-concurrent
2
3## 0.1.0.0 -- YYYY-mm-dd
4
5* First version. Released on an unsuspecting world.
diff --git a/lifted-concurrent/LICENSE b/lifted-concurrent/LICENSE
new file mode 100644
index 00000000..e8eaef49
--- /dev/null
+++ b/lifted-concurrent/LICENSE
@@ -0,0 +1,30 @@
1Copyright (c) 2019, James Crayne
2
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided
14 with the distribution.
15
16 * Neither the name of James Crayne nor the names of other
17 contributors may be used to endorse or promote products derived
18 from this software without specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/lifted-concurrent/Setup.hs b/lifted-concurrent/Setup.hs
new file mode 100644
index 00000000..9a994af6
--- /dev/null
+++ b/lifted-concurrent/Setup.hs
@@ -0,0 +1,2 @@
1import Distribution.Simple
2main = defaultMain
diff --git a/lifted-concurrent/lifted-concurrent.cabal b/lifted-concurrent/lifted-concurrent.cabal
new file mode 100644
index 00000000..3d8acba7
--- /dev/null
+++ b/lifted-concurrent/lifted-concurrent.cabal
@@ -0,0 +1,34 @@
1-- Initial lifted-concurrent.cabal generated by cabal init. For further
2-- documentation, see http://haskell.org/cabal/users-guide/
3
4name: lifted-concurrent
5version: 0.1.0.0
6-- synopsis:
7-- description:
8license: BSD3
9license-file: LICENSE
10author: James Crayne
11maintainer: jim.crayne@gmail.com
12-- copyright:
13-- category:
14build-type: Simple
15extra-source-files: CHANGELOG.md
16cabal-version: >=1.10
17
18library
19 exposed-modules:
20 Control.Concurrent.Lifted.Instrument
21 , Control.Concurrent.Async.Lifted.Instrument
22 other-modules: DebugTag
23 other-extensions: FlexibleContexts
24 build-depends:
25 base
26 , containers
27 , time
28 , lifted-async
29 , dput-hslogger
30 , lifted-base
31 , monad-control
32 , transformers-base
33 hs-source-dirs: src
34 default-language: Haskell2010
diff --git a/lifted-concurrent/src/Control/Concurrent/Async/Lifted/Instrument.hs b/lifted-concurrent/src/Control/Concurrent/Async/Lifted/Instrument.hs
new file mode 100644
index 00000000..eab0fadc
--- /dev/null
+++ b/lifted-concurrent/src/Control/Concurrent/Async/Lifted/Instrument.hs
@@ -0,0 +1,5 @@
1module Control.Concurrent.Async.Lifted.Instrument
2 ( module Control.Concurrent.Async.Lifted
3 ) where
4
5import Control.Concurrent.Async.Lifted
diff --git a/lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs b/lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs
new file mode 100644
index 00000000..fc3b6369
--- /dev/null
+++ b/lifted-concurrent/src/Control/Concurrent/Lifted/Instrument.hs
@@ -0,0 +1,98 @@
1{-# LANGUAGE FlexibleContexts #-}
2module Control.Concurrent.Lifted.Instrument
3 ( module Control.Concurrent.Lifted
4 , forkIO
5 , forkOS
6 , fork
7 , labelThread
8 , threadsInformation
9 , PerThread(..)
10 ) where
11
12import qualified Control.Concurrent.Lifted as Raw
13import Control.Concurrent.Lifted hiding (fork,forkOS)
14import Control.Exception (fromException)
15import Control.Monad.Trans.Control
16import System.IO.Unsafe
17import qualified Data.Map.Strict as Map
18import Control.Exception.Lifted
19import Control.Monad.Base
20import qualified GHC.Conc as GHC
21import Data.Time()
22import Data.Time.Clock
23import DPut
24import DebugTag
25
26
27data PerThread = PerThread
28 { lbl :: String
29 , startTime :: UTCTime
30 }
31 deriving (Eq,Ord,Show)
32
33data GlobalState = GlobalState
34 { threads :: !(Map.Map ThreadId PerThread)
35 , reportException :: String -> IO ()
36 }
37
38globals :: MVar GlobalState
39globals = unsafePerformIO $ newMVar $ GlobalState
40 { threads = Map.empty
41 , reportException = dput XMisc
42 }
43{-# NOINLINE globals #-}
44
45
46forkIO :: IO () -> IO ThreadId
47forkIO = instrumented GHC.forkIO
48{-# INLINE forkIO #-}
49
50forkOS :: MonadBaseControl IO m => m () -> m ThreadId
51forkOS = instrumented Raw.forkOS
52{-# INLINE forkOS #-}
53
54fork :: MonadBaseControl IO m => m () -> m ThreadId
55fork = instrumented Raw.fork
56{-# INLINE fork #-}
57
58instrumented :: MonadBaseControl IO m =>
59 (m () -> m ThreadId) -> m () -> m ThreadId
60instrumented rawFork action = do
61 t <- rawFork $ do
62 tid <- myThreadId
63 tm <- liftBase getCurrentTime
64 bracket_ (modifyThreads $! Map.insert tid (PerThread "" tm))
65 (return ())
66 $ do catch action $ \e -> case fromException e of
67 Just ThreadKilled -> return ()
68 Nothing -> liftBase $ do
69 g <- takeMVar globals
70 let l = concat [ show e
71 , " ("
72 , maybe "" lbl $ Map.lookup tid (threads g)
73 , ")"
74 ]
75 reportException g l
76 putMVar globals $! g { threads = Map.insert tid (PerThread l tm) $ threads g }
77 throwIO e
78 -- Remove the thread only if it terminated normally or was killed.
79 modifyThreads $! Map.delete tid
80 return t
81
82labelThread :: ThreadId -> String -> IO ()
83labelThread tid s = do
84 GHC.labelThread tid s
85 modifyThreads $! Map.adjust (\pt -> pt { lbl = s }) tid
86{-# INLINE labelThread #-}
87
88threadsInformation :: IO [(ThreadId,PerThread)]
89threadsInformation = do
90 m <- threads <$> readMVar globals
91 return $ Map.toList m
92
93
94modifyThreads :: MonadBase IO m => (Map.Map ThreadId PerThread -> Map.Map ThreadId PerThread) -> m ()
95modifyThreads f = do
96 g <- takeMVar globals
97 let f' st = st { threads = f (threads st) }
98 putMVar globals $! f' g
diff --git a/lifted-concurrent/src/DebugTag.hs b/lifted-concurrent/src/DebugTag.hs
new file mode 100644
index 00000000..9ac04bb0
--- /dev/null
+++ b/lifted-concurrent/src/DebugTag.hs
@@ -0,0 +1,24 @@
1module DebugTag where
2
3import Data.Typeable
4
5-- | Debug Tags, add more as needed, but ensure XAnnounce is always first, XMisc last
6data DebugTag
7 = XAnnounce
8 | XBitTorrent
9 | XDHT
10 | XLan
11 | XMan
12 | XNetCrypto
13 | XNetCryptoOut
14 | XOnion
15 | XRoutes
16 | XPing
17 | XRefresh
18 | XJabber
19 | XTCP
20 | XMisc
21 | XNodeinfoSearch
22 | XUnexpected -- Used only for special anomalous errors that we didn't expect to happen.
23 | XUnused -- Never commit code that uses XUnused.
24 deriving (Eq, Ord, Show, Read, Enum, Bounded,Typeable)