@@ -32,8 +32,9 @@
3232
3333module Streamly.Network.Socket
3434 (
35+ withSocket
3536 -- * Read from connection
36− fromSocket
37+ , fromSocket
3738 , read
3839 -- , readUtf8
3940 -- , readLines
@@ -64,7 +65,7 @@ module Streamly.Network.Socket
6465where
6566
6667import Control.Concurrent (threadWaitWrite, rtsSupportsBoundThreads)
67−import Control.Monad.Catch (MonadCatch)
68+import Control.Monad.Catch (MonadCatch, onException)
6869import Control.Monad.IO.Class (MonadIO(..))
6970import Control.Monad (when)
7071import Data.Word (Word8)
@@ -93,6 +94,16 @@ import qualified Streamly.Mem.Array as A
9394import qualified Streamly.Mem.Array.Types as A hiding (flattenArrays)
9495import qualified Streamly.Prelude as S
9596
97+-- | @'withSocket' socket act@ runs the computation @act@ passing the socket
98+-- handle to it. The handle will be closed on exit from 'withSocket', whether
99+-- by normal termination or by raising an exception. If closing the handle
100+-- raises an exception, then this exception will be raised by 'withSocket'
101+-- rather than any exception raised by 'act'.
102+withSocket :: (MonadCatch m, MonadIO m) => Socket -> (Socket -> m ()) -> m ()
103+withSocket sk f = do
104+ f sk `onException` liftIO (Net.close sk)
105+ liftIO (Net.close sk)
106+
96107-------------------------------------------------------------------------------
97108-- Array IO (Input)
98109-------------------------------------------------------------------------------