socket.socket.settimeout implementation

jnair at ensim.com jnair at ensim.com
Wed Apr 5 05:21:08 EDT 2006


When using socket.socket.settimeout we normally only guard against
"socket.timeout" exception.Now the implementation of "settimeout" in
"Python-2.4.3/Modules/socketmodule.c" sets the socket fd to
nonblocking and uses "select()" to timeout
as seen below in line 1487 and 1386 :

static PyObject *
  1470  sock_settimeout(PySocketSockObject *s, PyObject *arg)
  1471  {
  1472          double timeout;
  ..............................
  1485
  1486          s->sock_timeout = timeout;
  1487          internal_setblocking(s, timeout < 0.0);
  1488
  1489          Py_INCREF(Py_None);
  1490          return Py_None;
  1491  }
  1492

  1362  sock_accept(PySocketSockObject *s)
  1363  {
              ...

  1385     Py_BEGIN_ALLOW_THREADS
  1386     timeout = internal_select(s, 0);
  1387     if (!timeout)
  1388       newfd = accept(s->sock_fd, (struct sockaddr *)&addrbuf,
  1389                                 &addrlen);
  1390     Py_END_ALLOW_THREADS
  1391


Now internal_select()  returns "1" on timemout else "0"  as seen below
:

  673    n = select(s->sock_fd+1, &fds, NULL, NULL,&tv);
  674     if (n == 0)
  675            return 1;
  676          return 0;

back to the sock_accept() fuction on line 1387

1387  if (!timeout)
1388     newfd = accept(s->sock_fd, (struct sockaddr *) &addrbuf,
1389                                &addrlen)


if "select()" returned before timeout we call "accept()"

Now my observation on FC4 ( kernel version 2.6.11-1.1369_FC4)
"select()" can return  before timeout with a
"Interrupted system call" (EINTR) error,

my question is , is it possible that our internal_select() fuction as
seen on line 676 above returns "0" and we go on to do a "accept()" call
which returns with a  "Resource temporarily unavailable" error if the
sockfd is not readable. So user expects only "socket.timeout" but gets
"Resource temporarily unavailable" which stops the program
from proceeding.

Our Case : We are using CherryPy , which sets a timeout on socket using
"settimeout" and whenever our code uses "os.seteuid" cherrpy dies
giving
out the "Resource temporarily unavailable".

I did write a "C" program using pthreads , one thread doing
non blocking accept() and select()  and other thread doing a seteuid()
.
select() did bail out giving Interrupted system call Error.

Thanks
Jitendra Nair




More information about the Python-list mailing list