-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | High-level network sockets
--
-- This library provides a high-level abstraction for network sockets. It
-- uses Haskell2010 (along with GADTs) without typeclasses to ensure that
-- consumers of the API can only call appropriate functions on a socket.
--
-- Exceptions are tracked in the types of functions and returned to the
-- caller with Either. The caller is free to handle these
-- gracefully or to throw them. This library has another class of
-- exceptions described as _unrecoverable_. This library only throws
-- exceptions in three situations:
--
--
-- - The library detects that it has misused the operating system's
-- sockets API. This includes getting a sockaddr with an
-- unexpected socket family. It also includes getting an error code that
-- should not be possible. For example, the abstractions provided for
-- both datagram sockets and stream sockets mean that send system
-- calls in either context should never return the error code
-- ENOTCONN. Consequently, this error is treated as
-- unrecoverable.
-- - The caller asks for a negatively-sized slice of a buffer (such
-- exceptions indicate a mistake in the code consuming this API).
-- - A system call fails with ENOBUFS or ENOMEM. These
-- indicate that the operating system is out of memory. If this happens,
-- the Out Of Memory (OOM) manager is likely killing processes to reclaim
-- memory, so the process that received this message may be killed soon.
-- Making things even worse is that the GHC runtime requests pages of
-- memory from the operating system at times that are effectively
-- unpredictable to Haskell developers. (Most memory-managed languages
-- have this behavior). Any attempt to recover from ENOBUFS or
-- ENOMEM might cause the runtime to allocate memory from the
-- operating system. According to the documentation for the
-- HeapOverflow exception, an allocation failure at this point in
-- time (likely given the recent ENOBUFS/ENOMEM) would
-- result in immidiate termination of the program. So, although it is
-- technically possible to recover from ENOBUFS/ENOMEM, the
-- OOM killer and the GHC runtime make it impossible to do so reliably.
-- Consequently, these error codes are treated as fatal.
--
@package sockets
@version 0.4.0.0
module Socket.Address
posixToIPv4Peer :: SocketAddressInternet -> Peer
ipv4PeerToPosix :: Peer -> SocketAddressInternet
-- | Internet datagram sockets with a fixed destination.
module Socket.Datagram.IPv4.Connected
newtype Socket (a :: Connectedness) (b :: Family)
Socket :: Fd -> Socket
data Peer
Peer :: !IPv4 -> !Word16 -> Peer
[$sel:address:Peer] :: Peer -> !IPv4
[$sel:port:Peer] :: Peer -> !Word16
data Message
Message :: {-# UNPACK #-} !Peer -> !ByteArray -> Message
[$sel:peer:Message] :: Message -> {-# UNPACK #-} !Peer
[$sel:payload:Message] :: Message -> !ByteArray
withSocket :: Peer -> Peer -> (Socket 'Connected ( 'Internet 'V4) -> Word16 -> IO a) -> IO (Either SocketException a)
data SocketException
SocketPermissionDenied :: SocketException
SocketAddressInUse :: SocketException
SocketEphemeralPortsExhausted :: SocketException
SocketFileDescriptorLimit :: SocketException
-- | Internet datagram sockets without a fixed destination.
module Socket.Datagram.IPv4.Unconnected
newtype Socket (a :: Connectedness) (b :: Family)
Socket :: Fd -> Socket
data Peer
Peer :: !IPv4 -> !Word16 -> Peer
[$sel:address:Peer] :: Peer -> !IPv4
[$sel:port:Peer] :: Peer -> !Word16
data Message
Message :: {-# UNPACK #-} !Peer -> !ByteArray -> Message
[$sel:peer:Message] :: Message -> {-# UNPACK #-} !Peer
[$sel:payload:Message] :: Message -> !ByteArray
-- | Open a socket and run the supplied callback on it. This closes the
-- socket when the callback finishes or when an exception is thrown. Do
-- not return the socket from the callback. This leads to undefined
-- behavior. If the address 0.0.0.0 is used, the socket receives
-- on all network interfaces. If the port 0 is used, an unused port is
-- chosen by the operating system. The callback provides the chosen port
-- (or if the user specified a non-zero port, the chosen port will be
-- that value).
withSocket :: Peer -> (Socket 'Unconnected ( 'Internet 'V4) -> Word16 -> IO a) -> IO (Either SocketException a)
data SocketException
SocketPermissionDenied :: SocketException
SocketAddressInUse :: SocketException
SocketEphemeralPortsExhausted :: SocketException
SocketFileDescriptorLimit :: SocketException
module Socket.Datagram.Interruptible.MutableBytes
-- | Send a datagram using a socket with a pre-designated peer. This refers
-- to a datagram socket for which POSIX connect has locked down
-- communication to an individual peer.
send :: TVar Bool -> Socket 'Connected a -> MutableBytes RealWorld -> IO (Either (SendException 'Interruptible) ())
sendToIPv4 :: TVar Bool -> Socket 'Unconnected ( 'Internet 'V4) -> Peer -> MutableBytes RealWorld -> IO (Either (SendException 'Interruptible) ())
-- | Receive a datagram, discarding the peer address. This can be used with
-- datagram sockets of any family. It is usable with both connected and
-- unconnected datagram sockets.
receive :: TVar Bool -> Socket c a -> MutableBytes RealWorld -> IO (Either (ReceiveException 'Interruptible) Int)
receiveFromIPv4 :: TVar Bool -> Socket 'Unconnected ( 'Internet 'V4) -> MutableBytes RealWorld -> MutablePrimArrayOffset RealWorld SocketAddressInternet -> IO (Either (ReceiveException 'Interruptible) Int)
-- | Receive up to the specified number of datagrams into freshly allocated
-- byte arrays. When there are many datagrams present in the receive
-- buffer, this is more efficient than calling receive
-- repeatedly. This is guaranteed to fill the buffer with at least one
-- message.
--
-- The length buffer and the payload buffers arrange data in a
-- structure-of-arrays fashion. The size of the payload received into
-- payloads[j] is stored at lengths[j].
receiveMany :: TVar Bool -> Socket c a -> PeerlessSlab -> IO (Either (ReceiveException 'Interruptible) Int)
-- | Variant of receiveMany that provides that source address
-- corresponding to each datagram. This introduces another array to the
-- structure-of-arrays.
receiveManyFromIPv4 :: TVar Bool -> Socket 'Unconnected ( 'Internet 'V4) -> IPv4Slab -> IO (Either (ReceiveException 'Interruptible) Int)
module Socket.Datagram.Interruptible.Bytes
-- | Receive a datagram, discarding the peer address. This can be used with
-- datagram sockets of any family. It is usable with both connected and
-- unconnected datagram sockets.
receive :: TVar Bool -> Socket c a -> Int -> IO (Either (ReceiveException 'Interruptible) ByteArray)
receiveFromIPv4 :: TVar Bool -> Socket 'Unconnected ( 'Internet 'V4) -> Int -> IO (Either (ReceiveException 'Interruptible) Message)
receiveMany :: TVar Bool -> Socket 'Unconnected ( 'Internet 'V4) -> PeerlessSlab -> IO (Either (ReceiveException 'Interruptible) (UnliftedArray ByteArray))
receiveManyFromIPv4 :: TVar Bool -> Socket 'Unconnected ( 'Internet 'V4) -> IPv4Slab -> IO (Either (ReceiveException 'Interruptible) (SmallArray Message))
module Socket.Datagram.Slab
data PeerlessSlab
PeerlessSlab :: !MutablePrimArray RealWorld CInt -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld) -> PeerlessSlab
[$sel:sizes:PeerlessSlab] :: PeerlessSlab -> !MutablePrimArray RealWorld CInt
[$sel:payloads:PeerlessSlab] :: PeerlessSlab -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld)
data IPv4Slab
IPv4Slab :: !MutablePrimArray RealWorld CInt -> !MutablePrimArray RealWorld SocketAddressInternet -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld) -> IPv4Slab
[$sel:sizes:IPv4Slab] :: IPv4Slab -> !MutablePrimArray RealWorld CInt
[$sel:peers:IPv4Slab] :: IPv4Slab -> !MutablePrimArray RealWorld SocketAddressInternet
[$sel:payloads:IPv4Slab] :: IPv4Slab -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld)
newPeerlessSlab :: Int -> Int -> IO PeerlessSlab
newIPv4Slab :: Int -> Int -> IO IPv4Slab
freezePeerlessSlab :: PeerlessSlab -> Int -> IO (UnliftedArray ByteArray)
freezeIPv4Slab :: IPv4Slab -> Int -> IO (SmallArray Message)
module Socket.Datagram.Uninterruptible.MutableBytes
-- | Send a datagram using a socket with a pre-designated peer. This refers
-- to a datagram socket for which POSIX connect has locked down
-- communication to an individual peer.
send :: Socket 'Connected a -> MutableBytes RealWorld -> IO (Either (SendException 'Uninterruptible) ())
sendToIPv4 :: Socket 'Unconnected ( 'Internet 'V4) -> Peer -> MutableBytes RealWorld -> IO (Either (SendException 'Uninterruptible) ())
-- | Receive a datagram, discarding the peer address. This can be used with
-- datagram sockets of any family. It is usable with both connected and
-- unconnected datagram sockets.
receive :: Socket c a -> MutableBytes RealWorld -> IO (Either (ReceiveException 'Uninterruptible) Int)
receiveFromIPv4 :: Socket 'Unconnected ( 'Internet 'V4) -> MutableBytes RealWorld -> MutablePrimArrayOffset RealWorld SocketAddressInternet -> IO (Either (ReceiveException 'Uninterruptible) Int)
-- | Receive up to the specified number of datagrams into freshly allocated
-- byte arrays. When there are many datagrams present in the receive
-- buffer, this is more efficient than calling receive
-- repeatedly. This is guaranteed to fill the buffer with at least one
-- message.
--
-- The length buffer and the payload buffers arrange data in a
-- structure-of-arrays fashion. The size of the payload received into
-- payloads[j] is stored at lengths[j].
receiveMany :: Socket c a -> PeerlessSlab -> IO (Either (ReceiveException 'Uninterruptible) Int)
-- | Variant of receiveMany that provides that source address
-- corresponding to each datagram. This introduces another array to the
-- structure-of-arrays.
receiveManyFromIPv4 :: Socket 'Unconnected ( 'Internet 'V4) -> IPv4Slab -> IO (Either (ReceiveException 'Uninterruptible) Int)
data PeerlessSlab
PeerlessSlab :: !MutablePrimArray RealWorld CInt -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld) -> PeerlessSlab
[$sel:sizes:PeerlessSlab] :: PeerlessSlab -> !MutablePrimArray RealWorld CInt
[$sel:payloads:PeerlessSlab] :: PeerlessSlab -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld)
data IPv4Slab
IPv4Slab :: !MutablePrimArray RealWorld CInt -> !MutablePrimArray RealWorld SocketAddressInternet -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld) -> IPv4Slab
[$sel:sizes:IPv4Slab] :: IPv4Slab -> !MutablePrimArray RealWorld CInt
[$sel:peers:IPv4Slab] :: IPv4Slab -> !MutablePrimArray RealWorld SocketAddressInternet
[$sel:payloads:IPv4Slab] :: IPv4Slab -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld)
newPeerlessSlab :: Int -> Int -> IO PeerlessSlab
newIPv4Slab :: Int -> Int -> IO IPv4Slab
module Socket.Datagram.Uninterruptible.Bytes
-- | Send a datagram using a socket with a pre-designated peer. This refers
-- to a datagram socket for which POSIX connect has locked down
-- communication to an individual peer.
send :: Socket 'Connected a -> Bytes -> IO (Either (SendException 'Uninterruptible) ())
sendToIPv4 :: Socket 'Unconnected ( 'Internet 'V4) -> Peer -> Bytes -> IO (Either (SendException 'Uninterruptible) ())
-- | Receive a datagram, discarding the peer address. This can be used with
-- datagram sockets of any family. It is usable with both connected and
-- unconnected datagram sockets.
receive :: Socket c a -> Int -> IO (Either (ReceiveException 'Uninterruptible) ByteArray)
receiveFromIPv4 :: Socket 'Unconnected ( 'Internet 'V4) -> Int -> IO (Either (ReceiveException 'Uninterruptible) Message)
receiveMany :: Socket 'Unconnected ( 'Internet 'V4) -> PeerlessSlab -> IO (Either (ReceiveException 'Uninterruptible) (UnliftedArray ByteArray))
receiveManyFromIPv4 :: Socket 'Unconnected ( 'Internet 'V4) -> IPv4Slab -> IO (Either (ReceiveException 'Uninterruptible) (SmallArray Message))
data Message
Message :: {-# UNPACK #-} !Peer -> !ByteArray -> Message
[$sel:peer:Message] :: Message -> {-# UNPACK #-} !Peer
[$sel:payload:Message] :: Message -> !ByteArray
data Peer
Peer :: !IPv4 -> !Word16 -> Peer
[$sel:address:Peer] :: Peer -> !IPv4
[$sel:port:Peer] :: Peer -> !Word16
data ReceiveException (a :: Interruptibility)
[ReceiveTruncated] :: forall (a :: Interruptibility). () => !Int -> ReceiveException a
[ReceiveInterrupted] :: forall (a :: Interruptibility). () => ReceiveException Interruptible
data PeerlessSlab
PeerlessSlab :: !MutablePrimArray RealWorld CInt -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld) -> PeerlessSlab
[$sel:sizes:PeerlessSlab] :: PeerlessSlab -> !MutablePrimArray RealWorld CInt
[$sel:payloads:PeerlessSlab] :: PeerlessSlab -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld)
data IPv4Slab
IPv4Slab :: !MutablePrimArray RealWorld CInt -> !MutablePrimArray RealWorld SocketAddressInternet -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld) -> IPv4Slab
[$sel:sizes:IPv4Slab] :: IPv4Slab -> !MutablePrimArray RealWorld CInt
[$sel:peers:IPv4Slab] :: IPv4Slab -> !MutablePrimArray RealWorld SocketAddressInternet
[$sel:payloads:IPv4Slab] :: IPv4Slab -> !MutableUnliftedArray RealWorld (MutableByteArray RealWorld)
newPeerlessSlab :: Int -> Int -> IO PeerlessSlab
newIPv4Slab :: Int -> Int -> IO IPv4Slab
module Socket.Stream.IPv4
-- | A socket that listens for incomming connections.
data Listener
newtype Connection
Connection :: Fd -> Connection
data Peer
Peer :: !IPv4 -> !Word16 -> Peer
[$sel:address:Peer] :: Peer -> !IPv4
[$sel:port:Peer] :: Peer -> !Word16
-- | Open a socket that is used to listen for inbound connections.
withListener :: Peer -> (Listener -> Word16 -> IO a) -> IO (Either SocketException a)
-- | Accept a connection on the listener and run the supplied callback on
-- it. This closes the connection when the callback finishes or if an
-- exception is thrown. Since this function blocks the thread until the
-- callback finishes, it is only suitable for stream socket clients that
-- handle one connection at a time. The variant
-- forkAcceptedUnmasked is preferrable for servers that need to
-- handle connections concurrently (most use cases).
withAccepted :: Listener -> (Either CloseException () -> a -> IO b) -> (Connection -> Peer -> IO a) -> IO (Either (AcceptException 'Uninterruptible) b)
-- | Establish a connection to a server.
withConnection :: Peer -> (Either CloseException () -> a -> IO b) -> (Connection -> IO a) -> IO (Either (ConnectException ( 'Internet 'V4) 'Uninterruptible) b)
-- | Accept a connection on the listener and run the supplied callback in a
-- new thread. Prefer forkAcceptedUnmasked unless the masking
-- state needs to be preserved for the callback. Such a situation seems
-- unlikely to the author.
forkAccepted :: Listener -> (Either CloseException () -> a -> IO ()) -> (Connection -> Peer -> IO a) -> IO (Either (AcceptException 'Uninterruptible) ThreadId)
-- | Accept a connection on the listener and run the supplied callback in a
-- new thread. The masking state is set to Unmasked when running
-- the callback. Typically, a is instantiated to ().
forkAcceptedUnmasked :: Listener -> (Either CloseException () -> a -> IO ()) -> (Connection -> Peer -> IO a) -> IO (Either (AcceptException 'Uninterruptible) ThreadId)
-- | Accept a connection on the listener and run the supplied callback in a
-- new thread. The masking state is set to Unmasked when running
-- the callback. Typically, a is instantiated to ().
--
-- Discussion
--
-- Why is the counter argument present? At first, it seems like
-- this is something that the API consumer should implement on top of
-- this library. The argument for the inclusion of the counter is has two
-- parts: (1) clients supporting graceful termination always need these
-- semantics and (2) these semantics cannot be provided without building
-- in counter as a TVar.
--
--
-- - Clients supporting graceful termination always need these
-- semantics. To gracefully bring down a server that has been accepting
-- connections with a forking function, an application must wait for all
-- active connections to finish. Since all connections run on separate
-- threads, this can only be accomplished by a concurrency primitive. The
-- straightforward solution is to wrap a counter with either
-- MVar or TVar. To complete graceful termination, the
-- application must block until the counter reaches zero.
-- - These semantics cannot be provided without building in
-- counter as a TVar. When abandon becomes
-- True, graceful termination begins. From this point onward, if
-- at any point the counter reaches zero, the application consuming this
-- API will complete termination. Consequently, we need the guarantee
-- that the counter does not increment after the abandon
-- transaction completes. If it did increment in this forbidden way (e.g.
-- if it was incremented some unspecified amount of time after a
-- connection was accepted), there would be a race condition in which the
-- application may terminate without giving the newly accepted connection
-- a chance to finish. Fortunately, STM gives us the composable
-- transaction we need to get this guarantee. To wait for an inbound
-- connection, we use:
--
--
--
-- (isReady,deregister) <- threadWaitReadSTM fd
-- shouldReceive <- atomically $ do
-- readTVar abandon >>= \case
-- True -> do
-- isReady
-- modifyTVar' counter (+1)
-- pure True
-- False -> pure False
--
--
-- This eliminates the window for the race condition. If a connection is
-- accepted, the counter is guaranteed to be incremented _before_
-- abandon becomes True. However, this code would be
-- more simple and would perform better if GHC's event manager used TVar
-- instead of STM.
interruptibleForkAcceptedUnmasked :: TVar Int -> TVar Bool -> Listener -> (Either CloseException () -> a -> IO ()) -> (Connection -> Peer -> IO a) -> IO (Either (AcceptException 'Interruptible) ThreadId)
data SendException (a :: Interruptibility)
[SendShutdown] :: forall (a :: Interruptibility). () => SendException a
[SendReset] :: forall (a :: Interruptibility). () => SendException a
[SendInterrupted] :: forall (a :: Interruptibility). () => !Int -> SendException Interruptible
data ReceiveException (a :: Interruptibility)
[ReceiveShutdown] :: forall (a :: Interruptibility). () => ReceiveException a
[ReceiveReset] :: forall (a :: Interruptibility). () => ReceiveException a
[ReceiveInterrupted] :: forall (a :: Interruptibility). () => !Int -> ReceiveException Interruptible
[ReceiveHostUnreachable] :: forall (a :: Interruptibility). () => ReceiveException a
data ConnectException (a :: Family) (b :: Interruptibility)
[ConnectFirewalled] :: forall (a :: Family) (b :: Interruptibility). () => ConnectException a b
[ConnectFileDescriptorLimit] :: forall (a :: Family) (b :: Interruptibility). () => ConnectException a b
[ConnectNetworkUnreachable] :: forall (a :: Family) (b :: Interruptibility) (v :: Version). () => ConnectException (Internet v) b
[ConnectHostUnreachable] :: forall (a :: Family) (b :: Interruptibility) (v :: Version). () => ConnectException (Internet v) b
[ConnectEphemeralPortsExhausted] :: forall (a :: Family) (b :: Interruptibility). () => ConnectException a b
[ConnectRefused] :: forall (a :: Family) (b :: Interruptibility). () => ConnectException a b
[ConnectTimeout] :: forall (a :: Family) (b :: Interruptibility). () => ConnectException a b
[ConnectProtocolType] :: forall (a :: Family) (b :: Interruptibility). () => ConnectException Unix b
[ConnectInterrupted] :: forall (a :: Family) (b :: Interruptibility). () => ConnectException a Interruptible
data SocketException
SocketPermissionDenied :: SocketException
SocketAddressInUse :: SocketException
SocketEphemeralPortsExhausted :: SocketException
SocketFileDescriptorLimit :: SocketException
data AcceptException (a :: Interruptibility)
[AcceptConnectionAborted] :: forall (a :: Interruptibility). () => AcceptException a
[AcceptFileDescriptorLimit] :: forall (a :: Interruptibility). () => AcceptException a
[AcceptFirewalled] :: forall (a :: Interruptibility). () => AcceptException a
[AcceptInterrupted] :: forall (a :: Interruptibility). () => AcceptException Interruptible
data CloseException
ClosePeerContinuedSending :: CloseException
data Interruptibility
Interruptible :: Interruptibility
Uninterruptible :: Interruptibility
data Family
Internet :: Version -> Family
Unix :: Family
data Version
V4 :: Version
V6 :: Version
-- | Open a socket that can be used to listen for inbound connections.
-- Requirements:
--
--
-- - This function may only be called in contexts where exceptions are
-- masked.
-- - The caller must be sure to call unlistener on the
-- resulting Listener exactly once to close underlying file
-- descriptor.
-- - The Listener cannot be used after being given as an
-- argument to unlistener.
--
--
-- Noncompliant use of this function leads to undefined behavior. Prefer
-- withListener unless you are writing an integration with a
-- resource-management library.
listen :: Peer -> IO (Either SocketException (Listener, Word16))
-- | Close a listener. This throws an unrecoverable exception if the socket
-- cannot be closed.
unlisten :: Listener -> IO ()
-- | Close a listener. This does not check to see whether or not the
-- operating system successfully closed the socket. It never throws
-- exceptions of any kind. This should only be preferred to
-- unlistener in exception-cleanup contexts where there is
-- already an exception that will be rethrown. See the implementation of
-- withListener for an example of appropriate use of both
-- unlistener and unlistener_.
unlisten_ :: Listener -> IO ()
-- | Open a socket and connect to a peer. Requirements:
--
--
-- - This function may only be called in contexts where exceptions are
-- masked.
-- - The caller must be sure to call disconnect or
-- disconnect_ on the resulting Connection exactly once to
-- close underlying file descriptor.
-- - The Connection cannot be used after being given as an
-- argument to disconnect or disconnect_.
--
--
-- Noncompliant use of this function leads to undefined behavior. Prefer
-- withConnection unless you are writing an integration with a
-- resource-management library.
connect :: Peer -> IO (Either (ConnectException ( 'Internet 'V4) 'Uninterruptible) Connection)
-- | Close a connection gracefully, reporting a CloseException when
-- the connection has to be terminated by sending a TCP reset. This uses
-- a combination of shutdown, recv, close to
-- detect when resets need to be sent.
disconnect :: Connection -> IO (Either CloseException ())
-- | Close a connection. This does not check to see whether or not the
-- connection was brought down gracefully. It just calls close
-- and is likely to cause a TCP reset to be sent. It never throws
-- exceptions of any kind (even if close fails). This should
-- only be preferred to disconnect in exception-cleanup contexts
-- where there is already an exception that will be rethrown. See the
-- implementation of withConnection for an example of appropriate
-- use of both disconnect and disconnect_.
disconnect_ :: Connection -> IO ()
-- | Listen for an inbound connection.
accept :: Listener -> IO (Either (AcceptException 'Uninterruptible) (Connection, Peer))
-- | Listen for an inbound connection. Can be interrupted by an STM-style
-- interrupt.
interruptibleAccept :: TVar Bool -> Listener -> IO (Either (AcceptException 'Interruptible) (Connection, Peer))
module Socket.Stream.Interruptible.Addr
-- | Send an exact number of bytes starting from a given address. If
-- needed, this calls POSIX send repeatedly until the requested
-- number of bytes has been sent.
send :: TVar Bool -> Connection -> Addr -> Int -> IO (Either (SendException 'Interruptible) ())
-- | Receive the requested number of bytes into memory beginning at the
-- specified address. If needed, this may call recv repeatedly
-- until the requested number of bytes have been received.
receiveExactly :: TVar Bool -> Connection -> Addr -> Int -> IO (Either (ReceiveException 'Interruptible) ())
-- | Receive at most the specified number of bytes. This only makes
-- multiple calls to POSIX recv if EAGAIN is returned. It makes
-- at most one recv call that successfully fills the buffer.
receiveOnce :: TVar Bool -> Connection -> Addr -> Int -> IO (Either (ReceiveException 'Interruptible) Int)
-- | Receive a number of bytes that is between the inclusive lower and
-- upper bounds. If needed, this may call recv repeatedly until
-- the minimum requested number of bytes have been received.
receiveBetween :: TVar Bool -> Connection -> Addr -> Int -> Int -> IO (Either (ReceiveException 'Interruptible) Int)
module Socket.Stream.Interruptible.ByteString
-- | Send a slice of a buffer. If needed, this calls POSIX send
-- repeatedly until the entire contents of the buffer slice have been
-- sent.
send :: TVar Bool -> Connection -> ByteString -> IO (Either (SendException 'Interruptible) ())
-- | Receive a number of bytes exactly equal to the length of the buffer
-- slice. If needed, this may call recv repeatedly until the
-- requested number of bytes have been received.
receiveExactly :: TVar Bool -> Connection -> Int -> IO (Either (ReceiveException 'Interruptible) ByteString)
-- | Receive at most the specified number of bytes. This only makes
-- multiple calls to POSIX recv if EAGAIN is returned. It makes
-- at most one recv call that successfully fills the buffer.
receiveOnce :: TVar Bool -> Connection -> Int -> IO (Either (ReceiveException 'Interruptible) ByteString)
-- | Receive a number of bytes that is between the inclusive lower and
-- upper bounds. If needed, this may call recv repeatedly until
-- the minimum requested number of bytes have been received.
receiveBetween :: TVar Bool -> Connection -> Int -> Int -> IO (Either (ReceiveException 'Interruptible) ByteString)
module Socket.Stream.Interruptible.Bytes
-- | Send a slice of a buffer. If needed, this calls POSIX send
-- repeatedly until the entire contents of the buffer slice have been
-- sent.
send :: TVar Bool -> Connection -> Bytes -> IO (Either (SendException 'Interruptible) ())
-- | Receive a number of bytes exactly equal to the length of the buffer
-- slice. If needed, this may call recv repeatedly until the
-- requested number of bytes have been received.
receiveExactly :: TVar Bool -> Connection -> Int -> IO (Either (ReceiveException 'Interruptible) ByteArray)
-- | Receive at most the specified number of bytes. This only makes
-- multiple calls to POSIX recv if EAGAIN is returned. It makes
-- at most one recv call that successfully fills the buffer.
receiveOnce :: TVar Bool -> Connection -> Int -> IO (Either (ReceiveException 'Interruptible) ByteArray)
-- | Receive a number of bytes that is between the inclusive lower and
-- upper bounds. If needed, this may call recv repeatedly until
-- the minimum requested number of bytes have been received.
receiveBetween :: TVar Bool -> Connection -> Int -> Int -> IO (Either (ReceiveException 'Interruptible) ByteArray)
module Socket.Stream.Interruptible.Hybrid
sendMutableBytesUnmanagedBytes :: TVar Bool -> Connection -> MutableBytes RealWorld -> UnmanagedBytes -> IO (Either (SendException 'Interruptible) ())
module Socket.Stream.Interruptible.MutableBytes
-- | Send a slice of a buffer. If needed, this calls POSIX send
-- repeatedly until the entire contents of the buffer slice have been
-- sent.
send :: TVar Bool -> Connection -> MutableBytes RealWorld -> IO (Either (SendException 'Interruptible) ())
-- | Send as much of the buffer slice as there is space for in the TCP send
-- buffer. Returns the number of bytes sent.
sendOnce :: TVar Bool -> Connection -> MutableBytes RealWorld -> IO (Either (SendException 'Interruptible) Int)
-- | Receive a number of bytes exactly equal to the length of the buffer
-- slice. If needed, this may call recv repeatedly until the
-- requested number of bytes have been received.
receiveExactly :: TVar Bool -> Connection -> MutableBytes RealWorld -> IO (Either (ReceiveException 'Interruptible) ())
-- | Receive a number of bytes exactly equal to the length of the slice.
-- This only makes multiple calls to POSIX recv if EAGAIN is
-- returned. It makes at most one recv call that successfully
-- fills the buffer.
receiveOnce :: TVar Bool -> Connection -> MutableBytes RealWorld -> IO (Either (ReceiveException 'Interruptible) Int)
-- | Receive a number of bytes that is at least the minimum size and is at
-- most the length of the slice. If needed, this may call recv
-- repeatedly until the minimum requested number of bytes have been
-- received.
receiveBetween :: TVar Bool -> Connection -> MutableBytes RealWorld -> Int -> IO (Either (ReceiveException 'Interruptible) Int)
module Socket.Stream.Uninterruptible.Addr
-- | Send an exact number of bytes starting from a given address. If
-- needed, this calls POSIX send repeatedly until the requested
-- number of bytes has been sent.
send :: Connection -> Addr -> Int -> IO (Either (SendException 'Uninterruptible) ())
-- | Receive the requested number of bytes into memory beginning at the
-- specified address. If needed, this may call recv repeatedly
-- until the requested number of bytes have been received.
receiveExactly :: Connection -> Addr -> Int -> IO (Either (ReceiveException 'Uninterruptible) ())
-- | Receive at most the specified number of bytes. This only makes
-- multiple calls to POSIX recv if EAGAIN is returned. It makes
-- at most one recv call that successfully fills the buffer.
receiveOnce :: Connection -> Addr -> Int -> IO (Either (ReceiveException 'Uninterruptible) Int)
-- | Receive a number of bytes that is between the inclusive lower and
-- upper bounds. If needed, this may call recv repeatedly until
-- the minimum requested number of bytes have been received.
receiveBetween :: Connection -> Addr -> Int -> Int -> IO (Either (ReceiveException 'Uninterruptible) Int)
module Socket.Stream.Uninterruptible.ByteString
-- | Send a slice of a buffer. If needed, this calls POSIX send
-- repeatedly until the entire contents of the buffer slice have been
-- sent.
send :: Connection -> ByteString -> IO (Either (SendException 'Uninterruptible) ())
-- | Receive a number of bytes exactly equal to the length of the buffer
-- slice. If needed, this may call recv repeatedly until the
-- requested number of bytes have been received.
receiveExactly :: Connection -> Int -> IO (Either (ReceiveException 'Uninterruptible) ByteString)
-- | Receive at most the specified number of bytes. This only makes
-- multiple calls to POSIX recv if EAGAIN is returned. It makes
-- at most one recv call that successfully fills the buffer.
receiveOnce :: Connection -> Int -> IO (Either (ReceiveException 'Uninterruptible) ByteString)
-- | Receive a number of bytes that is between the inclusive lower and
-- upper bounds. If needed, this may call recv repeatedly until
-- the minimum requested number of bytes have been received.
receiveBetween :: Connection -> Int -> Int -> IO (Either (ReceiveException 'Uninterruptible) ByteString)
-- | Communicate over a connection using immutable byte arrays. Reception
-- functions return ByteArray instead of Bytes since this
-- result always takes up the entirity of a ByteArray. The
-- Bytes would have redundant information since the offset would
-- be zero and the length would be the length of the ByteArray
-- payload.
module Socket.Stream.Uninterruptible.Bytes
-- | Send a slice of a buffer. If needed, this calls POSIX send
-- repeatedly until the entire contents of the buffer slice have been
-- sent.
send :: Connection -> Bytes -> IO (Either (SendException 'Uninterruptible) ())
-- | Receive a number of bytes exactly equal to the length of the buffer
-- slice. If needed, this may call recv repeatedly until the
-- requested number of bytes have been received.
receiveExactly :: Connection -> Int -> IO (Either (ReceiveException 'Uninterruptible) ByteArray)
-- | Receive at most the specified number of bytes. This only makes
-- multiple calls to POSIX recv if EAGAIN is returned. It makes
-- at most one recv call that successfully fills the buffer.
receiveOnce :: Connection -> Int -> IO (Either (ReceiveException 'Uninterruptible) ByteArray)
-- | Receive a number of bytes that is between the inclusive lower and
-- upper bounds. If needed, this may call recv repeatedly until
-- the minimum requested number of bytes have been received.
receiveBetween :: Connection -> Int -> Int -> IO (Either (ReceiveException 'Uninterruptible) ByteArray)
module Socket.Stream.Uninterruptible.Hybrid
sendMutableBytesUnmanagedBytes :: Connection -> MutableBytes RealWorld -> UnmanagedBytes -> IO (Either (SendException 'Uninterruptible) ())
module Socket.Stream.Uninterruptible.MutableBytes
-- | Send a slice of a buffer. If needed, this calls POSIX send
-- repeatedly until the entire contents of the buffer slice have been
-- sent.
send :: Connection -> MutableBytes RealWorld -> IO (Either (SendException 'Uninterruptible) ())
-- | Receive a number of bytes exactly equal to the length of the buffer
-- slice. If needed, this may call recv repeatedly until the
-- requested number of bytes have been received.
receiveExactly :: Connection -> MutableBytes RealWorld -> IO (Either (ReceiveException 'Uninterruptible) ())
-- | Receive a number of bytes exactly equal to the length of the slice.
-- This only makes multiple calls to POSIX recv if EAGAIN is
-- returned. It makes at most one recv call that successfully
-- fills the buffer.
receiveOnce :: Connection -> MutableBytes RealWorld -> IO (Either (ReceiveException 'Uninterruptible) Int)
-- | Receive a number of bytes that is at least the minimum size and is at
-- most the length of the slice. If needed, this may call recv
-- repeatedly until the minimum requested number of bytes have been
-- received.
receiveBetween :: Connection -> MutableBytes RealWorld -> Int -> IO (Either (ReceiveException 'Uninterruptible) Int)