
Hi Warrick,
Thanks for your reply.
"Warrick Gray"
[redirecting to haskell-cafe]
[from the libraries list incidently]
I think I found an issue with the HTTP.hs library when making a short-lived non-persistent connection to a server from a slower machine (i486). I can also reproduce it by running my program with strace or ltrace on a faster machine (PIII).
recvfrom(3, 0x500a2008, 1000, 0, 0x500a23f8) = 0 getpeername(3, 0x500a241c, 0x500a2434, 0x080dfda0, 1) = 0
After no data is received the sending part of the TCP stream is closed:
shutdown(3, 1, 0x0805b85f, 0x080e018c, 1) = 0
Being polite, the library ensures that all incoming data has been consumed, forgetting for a moment that the incoming stream has already closed:
recvfrom(3, 0x500a2440, 1000, 0, 0x500a2830) = 0 getpeername(3, 0x500a2854, 0x500a286c, 0x080e018c, 1) = -1
The "recvfrom" seems fine, the "getpeername" call comes from the definition of Network.Socket.recvFrom, which features:
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
...Leading to the error in question:
strerror(107) = "Transport endpoint is not connec"...
The answer I guess is to alter all calls to 'recvFrom' to 'recv' calls (done),
Thanks, this helps, but now it fails for me sometimes (consistently on my slow machine) at the shutdown for the read side. Below is the tail of the strace output. BTW, wow! I didn't realise the implementation was so low level. There's no way to avoid that and get a faithful implementation, presumably?
or replace socket reference with ConnClosed at the first sign of a closed socket.
Sounds like this would probably solve the problem.
Unfortunately the second will have to wait, but the first is implemented and available in the latest version: http://homepages.paradise.net.nz/warrickg/haskell/http
Cheers, Jens recv(3, "", 1000, 0) = 0 shutdown(3, 1 /* send */) = 0 recv(3, "", 1000, 0) = 0 shutdown(3, 0 /* receive */) = -1 ENOTCONN (Transport endpoint is not connected) ioctl(1, SNDCTL_TMR_TIMEBASE, {B38400 opost isig icanon echo ...}) = 0 --- SIGVTALRM (Virtual timer expired) --- sigreturn() = ? (mask now []) fcntl(2, F_GETFL) = 0x8001 (flags O_WRONLY|O_LARGEFILE) write(2, "\nFail: ", 7 Fail: ) = 7 write(2, "invalid argument\nAction: shutdow"..., 78invalid argument Action: shutdown Reason: Transport endpoint is not connected ) = 78 write(2, "\n", 1 ) = 1 _exit(1) = ?