]> granicus.if.org Git - python/commitdiff
Add default timeout functionality. This adds setdefaulttimeout() and
authorGuido van Rossum <guido@python.org>
Thu, 18 Jul 2002 17:08:35 +0000 (17:08 +0000)
committerGuido van Rossum <guido@python.org>
Thu, 18 Jul 2002 17:08:35 +0000 (17:08 +0000)
getdefaulttimeout() functions to the socket and _socket modules, and
appropriate tests.

Lib/socket.py
Lib/test/test_socket.py
Modules/socketmodule.c

index bd0bfd7db485599f2d9ad5975970740c86bf80eb..c351a91cc2b8c906a62b5aaf8b7ba450e1acf29a 100644 (file)
@@ -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_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
 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!
 
index c9ef5d69958cc08aa0656fa42a6396f6ba93e4cb..b9b9db69eadc8c62d53909f8987b30317a8fd57e 100644 (file)
@@ -297,6 +297,36 @@ class GeneralModuleTests(unittest.TestCase):
             except socket.error:
                 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):
         """Testing getsockname()."""
         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
index 5314dcfc213a8e116c0f196df9c36619bc6a9306..9a3951681d5e0ccdb8043650e1e93ad297d495ac 100644 (file)
@@ -35,6 +35,8 @@ Module interface:
 - socket.AF_INET, socket.SOCK_STREAM, etc.: constants from <socket.h>
 - socket.inet_aton(IP address) -> 32-bit packed IP representation
 - 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)
   where hostname can be anything recognized by gethostbyname()
   (including the dd.dd.dd.dd notation) and port is in host byte order
@@ -521,6 +523,8 @@ internal_select(PySocketSockObject *s, int writing)
 
 /* Initialize a new socket object. */
 
+static float defaulttimeout = -1.0; /* Default timeout for new sockets */
+
 static void
 init_sockobject(PySocketSockObject *s,
                SOCKET_T fd, int family, int type, int proto)
@@ -532,9 +536,13 @@ init_sockobject(PySocketSockObject *s,
        s->sock_family = family;
        s->sock_type = type;
        s->sock_proto = proto;
-       s->sock_timeout = -1.0; /* Start without timeout */
+       s->sock_timeout = defaulttimeout;
 
        s->errorhandler = &set_error;
+
+       if (defaulttimeout >= 0.0)
+               internal_setblocking(s, 0);
+
 #ifdef RISCOS
        if (taskwindow)
                socketioctl(s->sock_fd, 0x80046679, (u_long*)&block);
@@ -2725,6 +2733,58 @@ PyDoc_STRVAR(getnameinfo_doc,
 \n\
 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. */
 
 static PyMethodDef socket_methods[] = {
@@ -2760,6 +2820,10 @@ static PyMethodDef socket_methods[] = {
         METH_VARARGS, getaddrinfo_doc},
        {"getnameinfo",         socket_getnameinfo,
         METH_VARARGS, getnameinfo_doc},
+       {"getdefaulttimeout",   socket_getdefaulttimeout,
+        METH_NOARGS, getdefaulttimeout_doc},
+       {"setdefaulttimeout",   socket_setdefaulttimeout,
+        METH_O, setdefaulttimeout_doc},
        {NULL,                  NULL}            /* Sentinel */
 };