/
Socket.hs
65 lines (58 loc) · 1.87 KB
/
Socket.hs
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
56
57
58
59
60
61
62
63
64
65
module PhiVty.Socket (
initSocket,
connect,
close,
send,
PhiSocket()
) where
import Network
import System.IO
import Control.Exception
import Control.Concurrent
data PhiSocket = PhiSocket {hostName :: MVar String, port :: MVar Int, internalHandle :: MVar Handle, recvThreadId :: MVar ThreadId}
initSocket :: String -> Int -> IO PhiSocket
initSocket addr pt = do
m_addr <- newMVar addr
m_port <- newMVar pt
m_handle <- newEmptyMVar
m_recv_thread_id <- newEmptyMVar
return $ PhiSocket {hostName = m_addr, port = m_port, internalHandle = m_handle, recvThreadId = m_recv_thread_id}
connect :: PhiSocket -> (String -> IO()) -> IO ()
connect soc recv_handler = do
close soc
addr <- readMVar $ hostName soc
pt <- readMVar $ port soc
hSetBuffering stdout NoBuffering
h <- connectTo addr (PortNumber $ fromIntegral pt)
hSetBuffering h LineBuffering
tId <- forkIO $ do
sequence_ $ repeat $ do
--have not to be retrieve?
--h <- readMVar $ internalHandle soc
res <- hGetLine h
recv_handler res
`catch` (\(SomeException _) -> return () )
`finally` do
hClose h
putMVar (internalHandle soc) h
putMVar (recvThreadId soc) tId
return ()
close :: PhiSocket -> IO ()
close soc = do
maybe_tid <- tryTakeMVar $ recvThreadId soc
_ <- tryTakeMVar $ internalHandle soc
case maybe_tid of
Nothing -> return ()
Just tid -> do
killThread tid
-- _ <- takeMVar (internalHandle soc)
return ()
send :: String -> PhiSocket -> IO ()
send mes soc = do
maybe_handle <- tryTakeMVar $ internalHandle soc
case maybe_handle of
Nothing -> return ()
Just internal_handle ->
hPutStrLn internal_handle mes
`catch` (\(SomeException _) -> return ())
`finally` putMVar (internalHandle soc) internal_handle