Commit 44c2fffd authored by Guido van Rossum's avatar Guido van Rossum

Add default timeout functionality. This adds setdefaulttimeout() and

getdefaulttimeout() functions to the socket and _socket modules, and
appropriate tests.
parent e10398d9
...@@ -21,6 +21,8 @@ htons(), htonl() -- convert 16, 32 bit int from host to network byte order ...@@ -21,6 +21,8 @@ htons(), htonl() -- convert 16, 32 bit int from host to network byte order
inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format
inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89) inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
ssl() -- secure socket layer support (only available if configured) ssl() -- secure socket layer support (only available if configured)
socket.getdefaulttimeout() -- get the default timeout value
socket.setdefaulttimeout() -- set the default timeout value
[*] not available on all platforms! [*] not available on all platforms!
......
...@@ -297,6 +297,36 @@ class GeneralModuleTests(unittest.TestCase): ...@@ -297,6 +297,36 @@ class GeneralModuleTests(unittest.TestCase):
except socket.error: except socket.error:
pass pass
def testDefaultTimeout(self):
"""Testing default timeout."""
# The default timeout should initially be None
self.assertEqual(socket.getdefaulttimeout(), None)
s = socket.socket()
self.assertEqual(s.gettimeout(), None)
s.close()
# Set the default timeout to 10, and see if it propagates
socket.setdefaulttimeout(10)
self.assertEqual(socket.getdefaulttimeout(), 10)
s = socket.socket()
self.assertEqual(s.gettimeout(), 10)
s.close()
# Reset the default timeout to None, and see if it propagates
socket.setdefaulttimeout(None)
self.assertEqual(socket.getdefaulttimeout(), None)
s = socket.socket()
self.assertEqual(s.gettimeout(), None)
s.close()
# Check that setting it to an invalid value raises ValueError
self.assertRaises(ValueError, socket.setdefaulttimeout, -1)
# Check that setting it to an invalid type raises TypeError
self.assertRaises(TypeError, socket.setdefaulttimeout, "spam")
# XXX The following three don't test module-level functionality...
def testSockName(self): def testSockName(self):
"""Testing getsockname().""" """Testing getsockname()."""
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
......
...@@ -35,6 +35,8 @@ Module interface: ...@@ -35,6 +35,8 @@ Module interface:
- socket.AF_INET, socket.SOCK_STREAM, etc.: constants from <socket.h> - socket.AF_INET, socket.SOCK_STREAM, etc.: constants from <socket.h>
- socket.inet_aton(IP address) -> 32-bit packed IP representation - socket.inet_aton(IP address) -> 32-bit packed IP representation
- socket.inet_ntoa(packed IP) -> IP address string - socket.inet_ntoa(packed IP) -> IP address string
- socket.getdefaulttimeout() -> None | float
- socket.setdefaulttimeout(None | float)
- an Internet socket address is a pair (hostname, port) - an Internet socket address is a pair (hostname, port)
where hostname can be anything recognized by gethostbyname() where hostname can be anything recognized by gethostbyname()
(including the dd.dd.dd.dd notation) and port is in host byte order (including the dd.dd.dd.dd notation) and port is in host byte order
...@@ -521,6 +523,8 @@ internal_select(PySocketSockObject *s, int writing) ...@@ -521,6 +523,8 @@ internal_select(PySocketSockObject *s, int writing)
/* Initialize a new socket object. */ /* Initialize a new socket object. */
static float defaulttimeout = -1.0; /* Default timeout for new sockets */
static void static void
init_sockobject(PySocketSockObject *s, init_sockobject(PySocketSockObject *s,
SOCKET_T fd, int family, int type, int proto) SOCKET_T fd, int family, int type, int proto)
...@@ -532,9 +536,13 @@ init_sockobject(PySocketSockObject *s, ...@@ -532,9 +536,13 @@ init_sockobject(PySocketSockObject *s,
s->sock_family = family; s->sock_family = family;
s->sock_type = type; s->sock_type = type;
s->sock_proto = proto; s->sock_proto = proto;
s->sock_timeout = -1.0; /* Start without timeout */ s->sock_timeout = defaulttimeout;
s->errorhandler = &set_error; s->errorhandler = &set_error;
if (defaulttimeout >= 0.0)
internal_setblocking(s, 0);
#ifdef RISCOS #ifdef RISCOS
if (taskwindow) if (taskwindow)
socketioctl(s->sock_fd, 0x80046679, (u_long*)&block); socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
...@@ -2725,6 +2733,58 @@ PyDoc_STRVAR(getnameinfo_doc, ...@@ -2725,6 +2733,58 @@ PyDoc_STRVAR(getnameinfo_doc,
\n\ \n\
Get host and port for a sockaddr."); Get host and port for a sockaddr.");
/* Python API to getting and setting the default timeout value. */
static PyObject *
socket_getdefaulttimeout(PyObject *self)
{
if (defaulttimeout < 0.0) {
Py_INCREF(Py_None);
return Py_None;
}
else
return PyFloat_FromDouble(defaulttimeout);
}
PyDoc_STRVAR(getdefaulttimeout_doc,
"socket.getdefaulttimeout() -> None | float\n\
\n\
Returns the default timeout in floating seconds for new socket objects.\n\
A value of None indicates that new socket objects have no timeout.\n\
When the socket module is first imported, the default is None.");
static PyObject *
socket_setdefaulttimeout(PyObject *self, PyObject *arg)
{
double timeout;
if (arg == Py_None)
timeout = -1.0;
else {
timeout = PyFloat_AsDouble(arg);
if (timeout < 0.0) {
if (!PyErr_Occurred())
PyErr_SetString(PyExc_ValueError,
"Timeout value out of range");
return NULL;
}
}
defaulttimeout = timeout;
Py_INCREF(Py_None);
return Py_None;
}
PyDoc_STRVAR(setdefaulttimeout_doc,
"socket.setdefaulttimeout(None | float)\n\
\n\
Set the default timeout in floating seconds for new socket objects.\n\
A value of None indicates that new socket objects have no timeout.\n\
When the socket module is first imported, the default is None.");
/* List of functions exported by this module. */ /* List of functions exported by this module. */
static PyMethodDef socket_methods[] = { static PyMethodDef socket_methods[] = {
...@@ -2760,6 +2820,10 @@ static PyMethodDef socket_methods[] = { ...@@ -2760,6 +2820,10 @@ static PyMethodDef socket_methods[] = {
METH_VARARGS, getaddrinfo_doc}, METH_VARARGS, getaddrinfo_doc},
{"getnameinfo", socket_getnameinfo, {"getnameinfo", socket_getnameinfo,
METH_VARARGS, getnameinfo_doc}, METH_VARARGS, getnameinfo_doc},
{"getdefaulttimeout", socket_getdefaulttimeout,
METH_NOARGS, getdefaulttimeout_doc},
{"setdefaulttimeout", socket_setdefaulttimeout,
METH_O, setdefaulttimeout_doc},
{NULL, NULL} /* Sentinel */ {NULL, NULL} /* Sentinel */
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment