Menu

#63 Timeout in DriverRecv?

Bug
closed
nobody
5
2020-12-27
2006-07-24
Stephen
No

From:
http://sourceforge.net/mailarchive/forum.php?thread_id=23433606&forum_id=43966

The nssock driver does this:

case DriverRecv:
timeout.sec = sock->driver->recvwait;
n = Ns_SockRecvBufs(sock->sock, bufs, nbufs,
&timeout);
break;
case DriverSend:
timeout.sec = sock->driver->sendwait;
n = Ns_SockSendBufs(sock->sock, bufs, nbufs,
&timeout);
break;

...which is called by the driver thread to read the
request, headers
etc. It's a non-blocking socket, so why the timeout?

Ns_SockRecvBufs looks like this:

n = SockRecv(sock, bufs, nbufs);
if (n < 0
&& ns_sockerrno == EWOULDBLOCK
&& Ns_SockTimedWait(sock, NS_SOCK_READ,
timeoutPtr) == NS_OK) {
n = SockRecv(sock, bufs, nbufs);
}
return n;

i.e. if on the first attempt to read from the socket
the kernel returns
EWOULDBLOCK, wait for 30 seconds for something to arrive.

Sockets only return EWOULDBLOCK if they are in
non-blocking mode, and
there is nothing to read/write. It's in non-blocking
mode because we
want to multiplex all sockets efficiently in the
driver thread.

Ns_SockTimedWait calls poll() with a timeout. It
doesn't return until
data arrives or the timeout expires. So, this can
block the driver
thread for up to 30 seconds.

Does this make any sense?

It's hard to see how this would be triggered in
practice. We only
attempt to read from the socket if the poll loop
indicates the socket is
readable. However, the Linux man page for select()
(which also applies
to poll) does say:

Under Linux, select() may report a socket file
descriptor as
"ready for reading", while nevertheless a
subsequent read
blocks. This could for example happen
when data has
arrived but upon examination has wrong
checksum and is
discarded. There may be other circum-stances.
Thus it may be
safer to use O_NONBLOCK on sockets that should
not block.

We do use O_NONBLOCK, but then defeat that with an
extra 30 second
poll() timeout...

Discussion

  • Stephen

    Stephen - 2006-12-01
    • labels: --> NaviServer - libnsd, libnsthread, nsd
    • milestone: --> 469714
     
  • Stephen

    Stephen - 2006-12-01
    • milestone: 469714 --> 473033
     
  • Stephen

    Stephen - 2006-12-01
    • milestone: 473033 --> Bug
     
  • gustafn

    gustafn - 2020-12-27
    • labels: NaviServer - libnsd, libnsthread, nsd --> NaviServer - libnsd, libnsthread, nsd
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,4 +1,3 @@
    -
     From:
     http://sourceforge.net/mailarchive/forum.php?thread\_id=23433606&amp;forum\_id=43966
    
    • status: open --> closed
     
  • gustafn

    gustafn - 2020-12-27

    The code has been rewritten several time since the bug report. All of Driver-IO is non-blocking. The receive operation performs the timeout wait operation only, when a timeout is provided.

     

Log in to post a comment.

MongoDB Logo MongoDB