diff options
Diffstat (limited to 'Presence/LockedChan.hs')
-rw-r--r-- | Presence/LockedChan.hs | 78 |
1 files changed, 0 insertions, 78 deletions
diff --git a/Presence/LockedChan.hs b/Presence/LockedChan.hs deleted file mode 100644 index eac2b5ad..00000000 --- a/Presence/LockedChan.hs +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | {-# LANGUAGE CPP #-} | ||
2 | module LockedChan | ||
3 | ( LockedChan | ||
4 | , cloneLChan | ||
5 | , newLockedChan | ||
6 | , peekLChan | ||
7 | , unlockChan | ||
8 | , writeLChan ) | ||
9 | where | ||
10 | |||
11 | |||
12 | import Control.Monad.STM | ||
13 | import Control.Concurrent.STM | ||
14 | |||
15 | data LockedChan a = LockedChan | ||
16 | { lock :: TVar Bool | ||
17 | , chan :: TChan a | ||
18 | } | ||
19 | |||
20 | unlockChan :: LockedChan a -> IO (TChan a) | ||
21 | unlockChan c = do | ||
22 | waslocked <- atomically $ swapTVar (lock c) False | ||
23 | if waslocked | ||
24 | then return (chan c) | ||
25 | else error "Attempt to read unlocked channel" | ||
26 | |||
27 | writeLChan :: LockedChan a -> a -> STM () | ||
28 | writeLChan c a = writeTChan (chan c) a | ||
29 | |||
30 | -- This one blocks rather than throwing an exception... | ||
31 | -- todo: probably this should be changed to conform to the rest | ||
32 | -- of the api. | ||
33 | peekLChan :: LockedChan a -> STM a | ||
34 | peekLChan c = do | ||
35 | readTVar (lock c) >>= check | ||
36 | peekTChan (chan c) | ||
37 | |||
38 | newLockedChan :: STM (LockedChan a) | ||
39 | newLockedChan = do | ||
40 | lock <- newTVar True | ||
41 | chan <- newTChan | ||
42 | return $ LockedChan lock chan | ||
43 | |||
44 | cloneLChan :: LockedChan a -> IO (LockedChan a) | ||
45 | cloneLChan c = do | ||
46 | mchan <- atomically $ do | ||
47 | locked <- readTVar (lock c) | ||
48 | if locked | ||
49 | then fmap Just $ do | ||
50 | c2 <- cloneTChan (chan c) | ||
51 | l2 <- newTVar True | ||
52 | return $ LockedChan l2 c2 | ||
53 | else return Nothing | ||
54 | maybe (do putStrLn "LockedChan: Attempt to clone unlocked channel" | ||
55 | error "Attempt to clone unlocked channel") | ||
56 | return | ||
57 | mchan | ||
58 | |||
59 | #if MIN_VERSION_stm(2,4,0) | ||
60 | #else | ||
61 | -- |Clone a 'TChan': similar to dupTChan, but the cloned channel starts with the | ||
62 | -- same content available as the original channel. | ||
63 | -- | ||
64 | -- Terrible inefficient implementation provided to build against older libraries. | ||
65 | cloneTChan :: TChan a -> STM (TChan a) | ||
66 | cloneTChan chan = do | ||
67 | contents <- chanContents' chan | ||
68 | chan2 <- dupTChan chan | ||
69 | mapM_ (writeTChan chan) contents | ||
70 | return chan2 | ||
71 | where | ||
72 | chanContents' chan = do | ||
73 | b <- isEmptyTChan chan | ||
74 | if b then return [] else do | ||
75 | x <- readTChan chan | ||
76 | xs <- chanContents' chan | ||
77 | return (x:xs) | ||
78 | #endif | ||