-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Network recv based on buffer pools
@package recv
@version 0.1.3


-- | This module provides efficient receiving functions from the network.
--   <a>recv</a> uses <tt>createAndTrim</tt> which behaves as follows:
--   
--   <ul>
--   <li>Allocates a buffer whose size is decided from the first
--   argument.</li>
--   <li>Receives data with the buffer.</li>
--   <li>Allocates another buffer whose size fits the received data.</li>
--   <li>Copies the data from the first buffer to the second buffer.</li>
--   </ul>
--   
--   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 <tt>recv</tt> 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.
module Network.Socket.BufferPool

-- | Type for the receiving function with a buffer pool.
type Recv = IO ByteString

-- | The receiving function with a buffer pool. The buffer pool is
--   automatically managed.
--   
--   <i>Caveats of <a>BufferPool</a> apply.</i>
receive :: Socket -> BufferPool -> Recv

-- | Like <a>receive</a> but never blocks and never involves the IO
--   manager: <a>Nothing</a> means no data was available (or an error
--   occurred, which a subsequent blocking <a>receive</a> will report
--   properly). <tt>Just ""</tt> is EOF.
--   
--   <i>Caveats of <a>BufferPool</a> apply.</i>
receiveNoWait :: Socket -> BufferPool -> IO (Maybe ByteString)

-- | Like <a>receive</a> but the caller can give up on it: whichever
--   settles first decides, <a>Left</a> when the <a>STM</a> action fires,
--   <a>Right</a> 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 <a>withReadable</a>; the give-up is read
--   there and nowhere else.
--   
--   Nothing is closed and no thread is interrupted to make this return.
--   
--   <i>Caveats of <a>BufferPool</a> apply.</i>
receiveWith :: Socket -> BufferPool -> STM a -> IO (Either a ByteString)

-- | Type for read buffer pool.
--   
--   <i>Caveats: designed to be used by one thread only.</i> <i>The buffer
--   is not behind a lock, so using a <a>BufferPool</a></i> <i>in more than
--   one thread might create race conditions.</i>
data BufferPool

-- | 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.
newBufferPool :: Int -> Int -> IO BufferPool

-- | 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 <a>Int</a>. The buffer in the buffer pool is
--   automatically managed.
--   
--   <i>Caveats of <a>BufferPool</a> apply.</i>
withBufferPool :: BufferPool -> (Buffer -> BufSize -> IO Int) -> IO ByteString

-- | L ike <a>withBufferPool</a> for fillers that can decline to fill: a
--   negative return value from the filler leaves the pool untouched and
--   produces <a>Nothing</a>.
--   
--   <i>Caveats of <a>BufferPool</a> apply.</i>
tryWithBufferPool :: BufferPool -> (Buffer -> BufSize -> IO Int) -> IO (Maybe ByteString)

-- | Type for the receiving function which receives N bytes.
type RecvN = Int -> IO ByteString

-- | 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.
--   
--   <pre>
--   &gt;&gt;&gt; :seti -XOverloadedStrings
--   
--   &gt;&gt;&gt; tryRecvN "a" 3 =&lt;&lt; _iorefRecv ["bcd"]
--   ("abc","d")
--   
--   &gt;&gt;&gt; tryRecvN "a" 3 =&lt;&lt; _iorefRecv ["bc"]
--   ("abc","")
--   
--   &gt;&gt;&gt; tryRecvN "a" 3 =&lt;&lt; _iorefRecv ["b"]
--   ("ab","")
--   </pre>
--   
--   <i>The resulting <a>RecvN</a> is designed to be used in one thread
--   only.</i>
makeRecvN :: ByteString -> Recv -> IO RecvN

-- | Type for buffer.
type Buffer = Ptr Word8

-- | Type for buffer size.
type BufSize = Int

-- | Allocating a byte string.
mallocBS :: Int -> IO ByteString

-- | Copying the bytestring to the buffer. This function returns the point
--   where the next copy should start.
copy :: Buffer -> ByteString -> IO Buffer
