summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam T <pxqr.sta@gmail.com>2013-07-13 06:07:52 +0400
committerSam T <pxqr.sta@gmail.com>2013-07-13 06:07:52 +0400
commitbdc0a54c1137a1cb34d0659131a95c64276998da (patch)
treeb24c2de6d8cb29887f27c7ebd642e771939b26ca
parenteecd91150b33d6363419daa8e0461984061ed06c (diff)
~ Isolate MVar operations.
-rw-r--r--src/Network/BitTorrent/Discovery.hs8
-rw-r--r--src/Network/BitTorrent/Internal.lhs28
2 files changed, 20 insertions, 16 deletions
diff --git a/src/Network/BitTorrent/Discovery.hs b/src/Network/BitTorrent/Discovery.hs
index 770ae818..1b9e7b26 100644
--- a/src/Network/BitTorrent/Discovery.hs
+++ b/src/Network/BitTorrent/Discovery.hs
@@ -41,16 +41,14 @@ discover swarm @ SwarmSession {..} action = {-# SCC discover #-} do
41 41
42startListener :: ClientSession -> PortNumber -> IO () 42startListener :: ClientSession -> PortNumber -> IO ()
43startListener cs @ ClientSession {..} port = 43startListener cs @ ClientSession {..} port =
44 putMVar peerListener =<< startService port (listener cs (error "listener")) 44 startService peerListener port $ listener cs (error "listener")
45 45
46startDHT :: ClientSession -> PortNumber -> IO () 46startDHT :: ClientSession -> PortNumber -> IO ()
47startDHT ClientSession {..} nodePort = do 47startDHT ClientSession {..} nodePort = withRunning peerListener failure start
48 maybe failure start =<< tryTakeMVar peerListener
49 where 48 where
50 start ClientService {..} = do 49 start ClientService {..} = do
51 ses <- newNodeSession servPort 50 ses <- newNodeSession servPort
52 serv <- startService nodePort (dhtServer ses) 51 startService nodeListener nodePort (dhtServer ses)
53 putMVar nodeListener serv
54 52
55 failure = throwIO $ userError msg 53 failure = throwIO $ userError msg
56 msg = "unable to start DHT server: peer listener is not running" 54 msg = "unable to start DHT server: peer listener is not running"
diff --git a/src/Network/BitTorrent/Internal.lhs b/src/Network/BitTorrent/Internal.lhs
index 8461a841..7edcc977 100644
--- a/src/Network/BitTorrent/Internal.lhs
+++ b/src/Network/BitTorrent/Internal.lhs
@@ -24,6 +24,8 @@
24> Progress(..), startProgress 24> Progress(..), startProgress
25> 25>
26> , ClientService(..) 26> , ClientService(..)
27> , startService
28> , withRunning
27> 29>
28> -- * Client 30> -- * Client
29> , ClientSession ( ClientSession 31> , ClientSession ( ClientSession
@@ -33,8 +35,6 @@
33> , withClientSession 35> , withClientSession
34> , listenerPort, dhtPort 36> , listenerPort, dhtPort
35> 37>
36> , startService
37>
38> , ThreadCount 38> , ThreadCount
39> , defaultThreadCount 39> , defaultThreadCount
40> 40>
@@ -96,7 +96,7 @@
96> import Control.Concurrent.STM 96> import Control.Concurrent.STM
97> import Control.Concurrent.MSem as MSem 97> import Control.Concurrent.MSem as MSem
98> import Control.Lens 98> import Control.Lens
99> import Control.Monad (when, forever) 99> import Control.Monad (when, forever, (>=>))
100> import Control.Exception 100> import Control.Exception
101> import Control.Monad.Trans 101> import Control.Monad.Trans
102 102
@@ -304,11 +304,20 @@ so we can abstract out into ClientService:
304> , servThread :: !ThreadId 304> , servThread :: !ThreadId
305> } deriving Show 305> } deriving Show
306 306
307> startService :: PortNumber -> (PortNumber -> IO ()) -> IO ClientService 307> startService :: MVar ClientService -> PortNumber -> (PortNumber -> IO ()) -> IO ()
308> startService port m = ClientService port <$> forkIO (m port) 308> startService s port m = do
309> stopService s
310> putMVar s =<< spawn
311> where
312> spawn = ClientService port <$> forkIO (m port)
309 313
310> stopService :: ClientService -> IO () 314> stopService :: MVar ClientService -> IO ()
311> stopService ClientService {..} = killThread servThread 315> stopService = tryTakeMVar >=> maybe (return ()) (killThread . servThread)
316
317Service A might depend on service B.
318
319> withRunning :: MVar ClientService -> IO () -> (ClientService -> IO ()) -> IO ()
320> withRunning dep failure action = tryTakeMVar dep >>= maybe failure action
312 321
313Client Sessions 322Client Sessions
314------------------------------------------------------------------------ 323------------------------------------------------------------------------
@@ -436,10 +445,7 @@ Retrieving client info
436 445
437> closeClientSession :: ClientSession -> IO () 446> closeClientSession :: ClientSession -> IO ()
438> closeClientSession ClientSession {..} = 447> closeClientSession ClientSession {..} =
439> maybeStop (tryTakeMVar peerListener) `finally` 448> stopService nodeListener `finally` stopService peerListener
440> maybeStop (tryTakeMVar nodeListener)
441> where
442> maybeStop m = maybe (return ()) stopService =<< m
443 449
444> withClientSession :: SessionCount -> [Extension] -> (ClientSession -> IO ()) -> IO () 450> withClientSession :: SessionCount -> [Extension] -> (ClientSession -> IO ()) -> IO ()
445> withClientSession c es = bracket (openClientSession c es) closeClientSession 451> withClientSession c es = bracket (openClientSession c es) closeClientSession