[PATCH] [rfc] Network.Socket: Add recvBuf

recently I have been looking into a latency-gap between the C and Haskell implementations of a TCP-echo One issue that has come up is that recvBufFrom calls getpeername() for each successful recvfrom(). This is unnecessary in the context of the code that I am working with as the result is discarded. My proposed solution to this is to implement recvBuf. I apologise in advance for my rudimentary Haskell skills. --- Network/Socket.hsc | 57 ++++++++++++++++++++++++++++++++++----------------- 1 files changed, 38 insertions(+), 19 deletions(-) diff --git a/Network/Socket.hsc b/Network/Socket.hsc index 21d83ac..13a94c2 100644 --- a/Network/Socket.hsc +++ b/Network/Socket.hsc @@ -81,6 +81,7 @@ module Network.Socket -- ** Sending and receiving -- $sendrecv , recv + , recvBuf , recvBufFrom , recvFrom , recvLen @@ -662,16 +663,10 @@ recvFrom sock nbytes = str <- peekCStringLen (ptr, len) return (str, len, sockaddr) --- | Receive data from the socket, writing it into buffer instead of --- creating a new string. The socket need not be in a connected --- state. Returns @(nbytes, address)@ where @nbytes@ is the number of --- bytes received and @address@ is a 'SockAddr' representing the --- address of the sending socket. --- -- NOTE: blocking on Windows unless you compile with -threaded (see -- GHC ticket #1129) -recvBufFrom :: Socket -> Ptr a -> Int -> IO (Int, SockAddr) -recvBufFrom sock@(MkSocket s family _stype _protocol _status) ptr nbytes +recvBufFrom' :: Socket -> Ptr a -> Int -> IO (Int, Ptr SockAddr) +recvBufFrom' sock@(MkSocket s family _stype _protocol _status) ptr nbytes | nbytes <= 0 = ioError (mkInvalidRecvArgError "Network.Socket.recvFrom") | otherwise = withNewSockAddr family $ \ptr_addr sz -> do @@ -687,17 +682,41 @@ recvBufFrom sock@(MkSocket s family _stype _protocol _status) ptr nbytes let len' = fromIntegral len if len' == 0 then ioError (mkEOFError "Network.Socket.recvFrom") - else do - flg <- sIsConnected sock - -- For at least one implementation (WinSock 2), recvfrom() ignores - -- filling in the sockaddr for connected TCP sockets. Cope with - -- this by using getPeerName instead. - sockaddr <- - if flg then - getPeerName sock - else - peekSockAddr ptr_addr - return (len', sockaddr) + else return (len', ptr_addr) + +-- | Receive data from the socket, writing it into buffer instead of +-- creating a new string. The socket need not be in a connected +-- state. Returns @(nbytes, address)@ where @nbytes@ is the number of +-- bytes received and @address@ is a 'SockAddr' representing the +-- address of the sending socket. +-- +-- NOTE: blocking on Windows unless you compile with -threaded (see +-- GHC ticket #1129) +recvBufFrom :: Socket -> Ptr a -> Int -> IO (Int, SockAddr) +recvBufFrom sock ptr nbytes = do + (len, ptr_addr) <- recvBufFrom' sock ptr nbytes + flg <- sIsConnected sock + -- For at least one implementation (WinSock 2), recvfrom() ignores + -- filling in the sockaddr for connected TCP sockets. Cope with + -- this by using getPeerName instead. + sockaddr <- + if flg then + getPeerName sock + else + peekSockAddr ptr_addr + return (len, sockaddr) + +-- | Receive data from the socket, writing it into buffer instead of +-- creating a new string. The socket need not be in a connected +-- state. Returns @(nbytes)@ where @nbytes@ is the number of +-- bytes received. +-- +-- NOTE: blocking on Windows unless you compile with -threaded (see +-- GHC ticket #1129) +recvBuf :: Socket -> Ptr a -> Int -> IO Int +recvBuf sock ptr nbytes = do + (len, ptr_addr) <- recvBufFrom' sock ptr nbytes + return len ----------------------------------------------------------------------------- -- send & recv -- 1.7.2.3

Hi Simon,
On Fri, Jan 7, 2011 at 2:08 AM, Simon Horman
recently I have been looking into a latency-gap between the C and Haskell implementations of a TCP-echo
One issue that has come up is that recvBufFrom calls getpeername() for each successful recvfrom(). This is unnecessary in the context of the code that I am working with as the result is discarded.
My proposed solution to this is to implement recvBuf.
I apologise in advance for my rudimentary Haskell skills.
Thanks for the patch. I've review and applied it. I'm working on a big overhaul to network so you will have to wait a few weeks to see your patch in a released version of network. If you need it right now I suggest working of HEAD until then. Johan

On Sun, Jan 09, 2011 at 02:37:12PM +0100, Johan Tibell wrote:
Hi Simon,
On Fri, Jan 7, 2011 at 2:08 AM, Simon Horman
wrote: recently I have been looking into a latency-gap between the C and Haskell implementations of a TCP-echo
One issue that has come up is that recvBufFrom calls getpeername() for each successful recvfrom(). This is unnecessary in the context of the code that I am working with as the result is discarded.
My proposed solution to this is to implement recvBuf.
I apologise in advance for my rudimentary Haskell skills.
Thanks for the patch. I've review and applied it.
I'm working on a big overhaul to network so you will have to wait a few weeks to see your patch in a released version of network. If you need it right now I suggest working of HEAD until then.
Thanks. I'm working off HEAD :-)
participants (2)
-
Johan Tibell
-
Simon Horman