diff options
author | Sam T <pxqr.sta@gmail.com> | 2013-07-13 06:07:52 +0400 |
---|---|---|
committer | Sam T <pxqr.sta@gmail.com> | 2013-07-13 06:07:52 +0400 |
commit | bdc0a54c1137a1cb34d0659131a95c64276998da (patch) | |
tree | b24c2de6d8cb29887f27c7ebd642e771939b26ca | |
parent | eecd91150b33d6363419daa8e0461984061ed06c (diff) |
~ Isolate MVar operations.
-rw-r--r-- | src/Network/BitTorrent/Discovery.hs | 8 | ||||
-rw-r--r-- | src/Network/BitTorrent/Internal.lhs | 28 |
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 | ||
42 | startListener :: ClientSession -> PortNumber -> IO () | 42 | startListener :: ClientSession -> PortNumber -> IO () |
43 | startListener cs @ ClientSession {..} port = | 43 | startListener cs @ ClientSession {..} port = |
44 | putMVar peerListener =<< startService port (listener cs (error "listener")) | 44 | startService peerListener port $ listener cs (error "listener") |
45 | 45 | ||
46 | startDHT :: ClientSession -> PortNumber -> IO () | 46 | startDHT :: ClientSession -> PortNumber -> IO () |
47 | startDHT ClientSession {..} nodePort = do | 47 | startDHT 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 | |||
317 | Service 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 | ||
313 | Client Sessions | 322 | Client 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 |