module Network.Transport.Util (spawn) where
import Network.Transport
( Transport
, EndPoint(..)
, EndPointAddress
, newEndPoint
)
import Control.Exception (throwIO)
import Control.Concurrent (forkIO)
import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar)
spawn :: Transport -> (EndPoint -> IO ()) -> IO EndPointAddress
spawn :: Transport -> (EndPoint -> IO ()) -> IO EndPointAddress
spawn Transport
transport EndPoint -> IO ()
proc = do
MVar (Either (TransportError NewEndPointErrorCode) EndPointAddress)
addrMVar <- IO
(MVar
(Either (TransportError NewEndPointErrorCode) EndPointAddress))
forall a. IO (MVar a)
newEmptyMVar
IO () -> IO ThreadId
forkIO (IO () -> IO ThreadId) -> IO () -> IO ThreadId
forall a b. (a -> b) -> a -> b
$ do
Either (TransportError NewEndPointErrorCode) EndPoint
mEndPoint <- Transport
-> IO (Either (TransportError NewEndPointErrorCode) EndPoint)
newEndPoint Transport
transport
case Either (TransportError NewEndPointErrorCode) EndPoint
mEndPoint of
Left TransportError NewEndPointErrorCode
err ->
MVar (Either (TransportError NewEndPointErrorCode) EndPointAddress)
-> Either (TransportError NewEndPointErrorCode) EndPointAddress
-> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Either (TransportError NewEndPointErrorCode) EndPointAddress)
addrMVar (TransportError NewEndPointErrorCode
-> Either (TransportError NewEndPointErrorCode) EndPointAddress
forall a b. a -> Either a b
Left TransportError NewEndPointErrorCode
err)
Right EndPoint
endPoint -> do
MVar (Either (TransportError NewEndPointErrorCode) EndPointAddress)
-> Either (TransportError NewEndPointErrorCode) EndPointAddress
-> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Either (TransportError NewEndPointErrorCode) EndPointAddress)
addrMVar (EndPointAddress
-> Either (TransportError NewEndPointErrorCode) EndPointAddress
forall a b. b -> Either a b
Right (EndPoint -> EndPointAddress
address EndPoint
endPoint))
EndPoint -> IO ()
proc EndPoint
endPoint
Either (TransportError NewEndPointErrorCode) EndPointAddress
mAddr <- MVar (Either (TransportError NewEndPointErrorCode) EndPointAddress)
-> IO
(Either (TransportError NewEndPointErrorCode) EndPointAddress)
forall a. MVar a -> IO a
takeMVar MVar (Either (TransportError NewEndPointErrorCode) EndPointAddress)
addrMVar
case Either (TransportError NewEndPointErrorCode) EndPointAddress
mAddr of
Left TransportError NewEndPointErrorCode
err -> TransportError NewEndPointErrorCode -> IO EndPointAddress
forall e a. Exception e => e -> IO a
throwIO TransportError NewEndPointErrorCode
err
Right EndPointAddress
addr -> EndPointAddress -> IO EndPointAddress
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return EndPointAddress
addr