summaryrefslogtreecommitdiff
path: root/Presence/LockedChan.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Presence/LockedChan.hs')
-rw-r--r--Presence/LockedChan.hs78
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 #-}
2module LockedChan
3 ( LockedChan
4 , cloneLChan
5 , newLockedChan
6 , peekLChan
7 , unlockChan
8 , writeLChan )
9 where
10
11
12import Control.Monad.STM
13import Control.Concurrent.STM
14
15data LockedChan a = LockedChan
16 { lock :: TVar Bool
17 , chan :: TChan a
18 }
19
20unlockChan :: LockedChan a -> IO (TChan a)
21unlockChan 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
27writeLChan :: LockedChan a -> a -> STM ()
28writeLChan 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.
33peekLChan :: LockedChan a -> STM a
34peekLChan c = do
35 readTVar (lock c) >>= check
36 peekTChan (chan c)
37
38newLockedChan :: STM (LockedChan a)
39newLockedChan = do
40 lock <- newTVar True
41 chan <- newTChan
42 return $ LockedChan lock chan
43
44cloneLChan :: LockedChan a -> IO (LockedChan a)
45cloneLChan 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.
65cloneTChan :: TChan a -> STM (TChan a)
66cloneTChan 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