| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Network.Socket.BufferPool
Description
This module provides efficient receiving functions from the network.
recv uses createAndTrim
which behaves as follows:
- Allocates a buffer whose size is decided from the first argument.
- Receives data with the buffer.
- Allocates another buffer whose size fits the received data.
- Copies the data from the first buffer to the second buffer.
On 64bit machines, the global lock is taken for the allocation of
a byte string whose length is larger than or equal to 3272 bytes.
So, for instance, if 4,096 is specified to recv and the size of
received data is 3,300, the global lock is taken twice with the copy
overhead.
The efficient receiving functions provided here use a buffer pool. A large buffer is allocated at the beginning and it is divided into a used one and a leftover when receiving. The latter is kept in the buffer pool and will be used next time. When the buffer gets small and usefless, a new large buffer is allocated.
Synopsis
- type Recv = IO ByteString
- receive :: Socket -> BufferPool -> Recv
- receiveNoWait :: Socket -> BufferPool -> IO (Maybe ByteString)
- receiveWith :: Socket -> BufferPool -> STM a -> IO (Either a ByteString)
- data BufferPool
- newBufferPool :: Int -> Int -> IO BufferPool
- withBufferPool :: BufferPool -> (Buffer -> BufSize -> IO Int) -> IO ByteString
- tryWithBufferPool :: BufferPool -> (Buffer -> BufSize -> IO Int) -> IO (Maybe ByteString)
- type RecvN = Int -> IO ByteString
- makeRecvN :: ByteString -> Recv -> IO RecvN
- type Buffer = Ptr Word8
- type BufSize = Int
- mallocBS :: Int -> IO ByteString
- copy :: Buffer -> ByteString -> IO Buffer
Recv
type Recv = IO ByteString Source #
Type for the receiving function with a buffer pool.
receive :: Socket -> BufferPool -> Recv Source #
The receiving function with a buffer pool. The buffer pool is automatically managed.
Caveats of BufferPool apply.
receiveNoWait :: Socket -> BufferPool -> IO (Maybe ByteString) Source #
Like receive but never blocks and never involves the IO manager:
Nothing means no data was available (or an error occurred, which a
subsequent blocking receive will report properly). Just "" is EOF.
Caveats of BufferPool apply.
receiveWith :: Socket -> BufferPool -> STM a -> IO (Either a ByteString) Source #
Like receive but the caller can give up on it: whichever settles
first decides, Left when the STM action fires, Right when data
arrives. Data already waiting is taken without blocking at all and
so wins over a caller which has given up, as a completed operation
does in withReadable; the give-up is read there
and nowhere else.
Nothing is closed and no thread is interrupted to make this return.
Caveats of BufferPool apply.
data BufferPool Source #
Type for read buffer pool.
Caveats: designed to be used by one thread only.
The buffer is not behind a lock, so using a BufferPool
in more than one thread might create race conditions.
newBufferPool :: Int -> Int -> IO BufferPool Source #
Creating a buffer pool. The first argument is the lower limit. When the size of the buffer in the poll is lower than this limit, the buffer is thrown awany (and is eventually freed). Then a new buffer is allocated. The second argument is the size for the new allocation.
withBufferPool :: BufferPool -> (Buffer -> BufSize -> IO Int) -> IO ByteString Source #
Using a buffer pool.
The second argument is a function which returns
how many bytes are filled in the buffer.
This function should return non negative Int.
The buffer in the buffer pool is automatically managed.
Caveats of BufferPool apply.
tryWithBufferPool :: BufferPool -> (Buffer -> BufSize -> IO Int) -> IO (Maybe ByteString) Source #
L ike withBufferPool for fillers that can decline to fill:
a negative return value from the filler leaves the pool untouched
and produces Nothing.
Caveats of BufferPool apply.
RecvN
makeRecvN :: ByteString -> Recv -> IO RecvN Source #
This function returns a receiving function based on two receiving functions. The returned function receives exactly N bytes. The first argument is an initial received data. After consuming the initial data, the two functions is used. When N is less than equal to 4096, the buffer pool is used. Otherwise, a new buffer is allocated. In this case, the global lock is taken.
>>>:seti -XOverloadedStrings>>>tryRecvN "a" 3 =<< _iorefRecv ["bcd"]("abc","d")>>>tryRecvN "a" 3 =<< _iorefRecv ["bc"]("abc","")>>>tryRecvN "a" 3 =<< _iorefRecv ["b"]("ab","")
The resulting RecvN is designed to be used in one thread only.