Safe Haskell | Safe-Infered |
---|
This library 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 – which allocates a single memory buffer in user address space,
then enters an inner loop that uses hGetBufSome
and
hPutBuf
. This avoids lots of tiny allocations as would otherwise
be caused by recv
and
sendAll
from the bytestring
package.
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
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 void 1024 (sourceSocket, _) (targetSocket, _) void . forkIO . tryWith handler $! splice void 1024 (targetSocket, _) (sourceSocket, _)
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.
- 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.
:: ChunkSize | maximal chunk size. |
-> (Socket, Maybe Handle) | source socket and possibly its opened handle. |
-> (Socket, Maybe Handle) | target socket and possibly its opened handle. |
-> IO () | infinite loop. |
Pipes data from one socket to another in an infinite loop.
splice
currently has two implementations:
- on GNU/Linux using
fdSplice
≅
splice len (sIn, _ ) (sOut, _ ) = ... fdSplice ...
- on all other operating systems using
hSplice
≅
splice len (_ , Just hIn) (_ , Just hOut) = ... hSplice ...
- Notes
-
fdSplice
andfdSplice
implementation ofsplice
are only available on GNU/Linux. -
hSplice
is always available and thehSplice
implementation ofsplice
can be forced on GNU/Linux by defining theportable
flag at compile time. -
hSplice
implementation requires handles inNoBuffering
mode. -
splice
is a terminal loop on two sockets and once entered its sockets and handles cannot be interleaved by other IO operations.
The numeric type to recommend chunk sizes for moving data between sockets
used by both zero-copy and portable implementations of splice
.
Indicates whether splice
uses zero-copy system calls or the portable user
space Haskell implementation.
Combinators for Exception Handling
:: (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 the single handler. |
:: IO () | action to run which can throw any exception. |
-> IO () | new action where exceptions are silenced. |
Similar to try
but used when an obvious exception
is expected which can be safely ignored.
Implementation Primitives
Infinite loops used in the cross-platform implementation of splice
.