splice 0.5.1 → 0.6
raw patch · 3 files changed
+35/−24 lines, 3 filessetup-changed
Files
- Setup.lhs +0/−1
- splice.cabal +9/−11
- src/Network/Socket/Splice/Internal.hsc +26/−12
Setup.lhs view
@@ -3,4 +3,3 @@ > import Distribution.Simple > main :: IO () > main = defaultMain -
splice.cabal view
@@ -1,25 +1,23 @@ name: splice-version: 0.5.1+version: 0.6 stability: stable on all operating systems-synopsis: Socket to Socket Data Splicing (supports all operating systems)+synopsis: Cross-platform Socket to Socket Data Splicing description: A library that implements most efficient socket to socket data transfer loops for proxy servers on each operating system. . On GNU/Linux, it uses and exposes the zero-copy @splice()@ system call: <http://kerneltrap.org/node/6505>. .- On all other operating systems, it currently falls back to a- portable Haskell implementation.+ On other operating systems, it falls back to a portable Haskell+ implementation. .- [Corsis Research]+ [Framework] This work is funded by Corsis Research (<http://corsis.eu>) for the development of- .- [PortFusion \]-\[ayabusa (はやぶさ) (Hayabusa)]- – German-Japanese joint research project for building the- simplest and most concise high-performance distributed reverse /- forward proxy application possible on commodity hardware and- operating systems+ PortFusion \]-\[ayabusa (はやぶさ) (Hayabusa) – German-Japanese+ joint research project for building the simplest and most concise+ high-performance distributed reverse / forward proxy application+ possible on commodity hardware and operating systems (<https://sourceforge.net/p/portfusion/wiki/RoadMap/>). license: BSD3 license-file: LICENSE
src/Network/Socket/Splice/Internal.hsc view
@@ -18,21 +18,30 @@ module Network.Socket.Splice.Internal ( -- * Cross-platform API for Socket to Socket Data Transfer Loops+ {- | 'splice' is the cross-platform API for continous, uni-directional data transfer between two network sockets. 'splice' and its implementation primitives 'hSplice' and 'fdSplice' are- /infinite/ loops that are intended to be used with exception handlers and- 'Control.Concurrent.forkIO'.+ /infinite/ loops that are intended to be used with+ 'Control.Concurrent.forkIO' and exception handlers. 'splice' is a+ terminal operation; it cannot be interleaved by other IO operations on+ its sockets or handles. [Initiate bi-directional continuous data transfer between two sockets:] > void . forkIO . tryWith handler $ splice 1024 (sourceSocket, _) (targetSocket, _) > void . forkIO . tryWith handler $ splice 1024 (targetSocket, _) (sourceSocket, _) - where @handler@ is an IO action that would do the necessary clean up –+ where @handler@ is an IO operation that would do the necessary clean up – such as ensuring the sockets are closed and any resources that may be- associated with the sockets are properly disposed of. + associated with the sockets are properly disposed of.++ [Notes]++ * 'c_splice', the Linux-only system call, is not a terminal infinite+ loop and can be safely interleaved by other IO operations on sockets+ or socket handles. -} splice@@ -127,6 +136,11 @@ -- 'splice' can be forced on GNU\/Linux by defining the @portable@ flag at -- compile time. --+-- * 'hSplice' implementation requires handles in 'NoBuffering' mode.+--+-- * 'splice' is a terminal loop on two sockets and once entered its sockets+-- and handles cannot be interleaved by other IO operations.+-- splice :: ChunkSize -- ^ chunk size. -> (Socket, Maybe Handle) -- ^ source socket and possibly its opened handle.@@ -192,12 +206,14 @@ 2. uses it until the loop terminates by exception 3. frees the buffer and returns++ [Notes]++ * the socket handles are required to be in 'NoBuffering' mode. -} hSplice :: Int -> Handle -> Handle -> IO () hSplice len s t = do - sb <- hGetBuffering s; hSetBuffering s NoBuffering- tb <- hGetBuffering t; hSetBuffering t NoBuffering a <- mallocBytes len :: IO (Ptr Word8) finally@@ -206,18 +222,16 @@ if bytes > 0 then hPutBuf t a bytes else throwRecv0)- (do free a- try_ $ hSetBuffering s sb- try_ $ hSetBuffering s tb)+ (free a) -- | Similar to 'Control.Exception.Base.try' but used when an obvious exception -- is expected and can be handled easily. Unlike 'finally' exceptions are--- not rethrown once handled.+-- /NOT/ rethrown once handled. tryWith :: (SomeException -> IO a) -- ^ exception handler.- -> IO a -- ^ action to run which can throw /any/ exception.- -> IO a -- ^ new action where all exceptions are handled by a single.+ -> IO a -- ^ action to run which can throw /any/ exception.+ -> IO a -- ^ new action where all exceptions are handled by the single handler. tryWith h a = try a >>= \r -> case r of Left x -> h x; Right y -> return y