1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
module Main where
import System.Mem.Weak (addFinalizer)
import Control.Concurrent (ThreadId, forkIO, threadDelay, killThread)
import Control.Concurrent.STM (TVar, newTVarIO, readTVar, writeTVar, atomically, retry)
import Control.Monad (when, forever, forM_)
data Socket = Socket ThreadId (TVar String)
open :: IO Socket
open = do
var <- newTVarIO ""
threadId <- forkIO (loop var)
let sock = Socket threadId var
addFinalizer sock $ do
putStrLn "finalizing"
killThread threadId
return sock
where
loop var = forever $ do
x <- atomically $ extract var
putStrLn x
extract var = do
x <- readTVar var
when (x == "") retry
writeTVar var ""
return x
send :: Socket -> String -> IO ()
send sock@(Socket _ var) msg = do
atomically $ do
x <- readTVar var
when (x /= "") retry
writeTVar var msg
main :: IO ()
main = do
socket <- open
forM_ [1..1000000] $ \x -> do
send socket (show x)
threadDelay (10*1000) |