tags:

views:

2930

answers:

7

Hi folks,

I would like to know if the following scenario is real?!

  1. select() (RD) on non-blocking TCP socket says that the socket is ready
  2. following recv() would return EWOULDBLOCK despite the call to select()
+2  A: 

It's possible, but only in a situation where you have multiple threads/processes trying to read from the same socket.

Harper Shelby
Glad to hear that. My application is single threaded so I am fine.
error.exit
+3  A: 

For recv() you would get EAGAIN rather than EWOULDBLOCK, and yes it is possible. Since you have just checked with select() then one of two things happened:

  • Something else (another thread) has drained the input buffer between select() and recv().
  • A receive timeout was set on the socket and it expired without data being received.
dwc
In case of timeout, select() returns 0 so I am not worried about it.
error.exit
A: 

It is possible in a multithreaded environment where two threads are reading from the socket. Is this a multithreaded application?

mikelong
It is a single threaded application.
error.exit
Even if there's a timeout on the socket rather than just a parameter to `select()`? What if the timeout happens between `select()` and `recv()`?
dwc
In this case you should not see this behaviour.
mikelong
What do you mean by saying "timeout on the socket"?
error.exit
A: 

If you do not call any other syscall between select() and recv() on this socket, then recv() will never return EAGAIN or EWOULDBLOCK.

I don't know what they mean with recv-timeout, however, the POSIX standard does not mention it here so you can be safe calling recv().

David Herrmann
+1  A: 

I am aware of an error in a popular desktop operating where O_NONBLOCK TCP sockets, particularly those running over the loopback interface, can sometimes return EAGAIN from recv() after select() reports the socket is ready for reading. In my case, this happens after the other side half-closes the sending stream.

For more details, see the source code for t_nx.ml in the NX library of my OCaml Network Application Environment distribution. ([link])

james woodyatt
Link seems broken
Thomas
A: 

Though my application is a single-threaded one, I noticed that the described behavior is not uncommon in RHEL5. Both with TCP and UDP sockets that were set to O_NONBLOCK (the only socket option that is set). select() reports that the socket is ready but the following recv() returns EAGAIN.

error.exit
+1  A: 

On Linux it's even documented that this can happen, as I read it.

See this question:

http://stackoverflow.com/questions/858282/spurious-readiness-notification-for-select-system-call

Thomas