summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorChristian Heimes <christian@cheimes.de>2008-02-28 20:02:27 (GMT)
committerChristian Heimes <christian@cheimes.de>2008-02-28 20:02:27 (GMT)
commit70e7ea23f18aacc31f429787645ff8c074c0ad86 (patch)
treebeb83e14c2f9fdd729914234d9979b50a70718c3 /Lib
parent9e7f1d2e965400edcb2c0cb7fee625ef2b595eb5 (diff)
downloadcpython-70e7ea23f18aacc31f429787645ff8c074c0ad86.zip
cpython-70e7ea23f18aacc31f429787645ff8c074c0ad86.tar.gz
cpython-70e7ea23f18aacc31f429787645ff8c074c0ad86.tar.bz2
Merged revisions 61038,61042-61045,61047,61050,61053,61055-61056,61061-61062,61066,61068,61070,61083,61085,61092-61097,61103-61108 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r61105 | andrew.kuchling | 2008-02-28 15:03:03 +0100 (Thu, 28 Feb 2008) | 1 line #2169: make generated HTML more valid ........ r61106 | jeffrey.yasskin | 2008-02-28 19:03:15 +0100 (Thu, 28 Feb 2008) | 4 lines Prevent SocketServer.ForkingMixIn from waiting on child processes that it didn't create, in most cases. When there are max_children handlers running, it will still wait for any child process, not just handler processes. ........ r61107 | raymond.hettinger | 2008-02-28 20:41:24 +0100 (Thu, 28 Feb 2008) | 1 line Document impending updates to itertools. ........ r61108 | martin.v.loewis | 2008-02-28 20:44:22 +0100 (Thu, 28 Feb 2008) | 1 line Add 2.6aN uuids. ........
Diffstat (limited to 'Lib')
-rw-r--r--Lib/SimpleHTTPServer.py7
-rw-r--r--Lib/SocketServer.py30
-rw-r--r--Lib/test/test_socketserver.py36
3 files changed, 51 insertions, 22 deletions
diff --git a/Lib/SimpleHTTPServer.py b/Lib/SimpleHTTPServer.py
index deedd4b..beb0a39 100644
--- a/Lib/SimpleHTTPServer.py
+++ b/Lib/SimpleHTTPServer.py
@@ -109,8 +109,9 @@ class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
list.sort(key=lambda a: a.lower())
f = StringIO()
displaypath = cgi.escape(urllib.unquote(self.path))
- f.write("<title>Directory listing for %s</title>\n" % displaypath)
- f.write("<h2>Directory listing for %s</h2>\n" % displaypath)
+ f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
+ f.write("<html>\n<title>Directory listing for %s</title>\n" % displaypath)
+ f.write("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)
f.write("<hr>\n<ul>\n")
for name in list:
fullname = os.path.join(path, name)
@@ -124,7 +125,7 @@ class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
# Note: a link to a directory displays with @ and links with /
f.write('<li><a href="%s">%s</a>\n'
% (urllib.quote(linkname), cgi.escape(displayname)))
- f.write("</ul>\n<hr>\n")
+ f.write("</ul>\n<hr>\n</body>\n</html>\n")
length = f.tell()
f.seek(0)
self.send_response(200)
diff --git a/Lib/SocketServer.py b/Lib/SocketServer.py
index 9c5d4c2..47d8728 100644
--- a/Lib/SocketServer.py
+++ b/Lib/SocketServer.py
@@ -440,18 +440,30 @@ class ForkingMixIn:
def collect_children(self):
"""Internal routine to wait for children that have exited."""
- while self.active_children:
- if len(self.active_children) < self.max_children:
- options = os.WNOHANG
- else:
- # If the maximum number of children are already
- # running, block while waiting for a child to exit
- options = 0
+ if self.active_children is None: return
+ while len(self.active_children) >= self.max_children:
+ # XXX: This will wait for any child process, not just ones
+ # spawned by this library. This could confuse other
+ # libraries that expect to be able to wait for their own
+ # children.
try:
- pid, status = os.waitpid(0, options)
+ pid, status = os.waitpid(0, options=0)
except os.error:
pid = None
- if not pid: break
+ if pid not in self.active_children: continue
+ self.active_children.remove(pid)
+
+ # XXX: This loop runs more system calls than it ought
+ # to. There should be a way to put the active_children into a
+ # process group and then use os.waitpid(-pgid) to wait for any
+ # of that set, but I couldn't find a way to allocate pgids
+ # that couldn't collide.
+ for child in self.active_children:
+ try:
+ pid, status = os.waitpid(child, os.WNOHANG)
+ except os.error:
+ pid = None
+ if not pid: continue
try:
self.active_children.remove(pid)
except ValueError as e:
diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py
index 25734fd..658056c 100644
--- a/Lib/test/test_socketserver.py
+++ b/Lib/test/test_socketserver.py
@@ -2,6 +2,7 @@
Test suite for SocketServer.py.
"""
+import contextlib
import errno
import imp
import os
@@ -109,6 +110,18 @@ class ServerThread(threading.Thread):
if verbose: print("thread: done")
+@contextlib.contextmanager
+def simple_subprocess(testcase):
+ pid = os.fork()
+ if pid == 0:
+ # Don't throw an exception; it would be caught by the test harness.
+ os._exit(72)
+ yield None
+ pid2, status = os.waitpid(pid, 0)
+ testcase.assertEquals(pid2, pid)
+ testcase.assertEquals(72 << 8, status)
+
+
class SocketServerTest(unittest.TestCase):
"""Test all socket servers."""
@@ -211,10 +224,11 @@ class SocketServerTest(unittest.TestCase):
self.stream_examine)
if HAVE_FORKING:
- def test_ThreadingTCPServer(self):
- self.run_server(SocketServer.ForkingTCPServer,
- SocketServer.StreamRequestHandler,
- self.stream_examine)
+ def test_ForkingTCPServer(self):
+ with simple_subprocess(self):
+ self.run_server(SocketServer.ForkingTCPServer,
+ SocketServer.StreamRequestHandler,
+ self.stream_examine)
if HAVE_UNIX_SOCKETS:
def test_UnixStreamServer(self):
@@ -229,9 +243,10 @@ class SocketServerTest(unittest.TestCase):
if HAVE_FORKING:
def test_ForkingUnixStreamServer(self):
- self.run_server(ForkingUnixStreamServer,
- SocketServer.StreamRequestHandler,
- self.stream_examine)
+ with simple_subprocess(self):
+ self.run_server(ForkingUnixStreamServer,
+ SocketServer.StreamRequestHandler,
+ self.stream_examine)
def test_UDPServer(self):
self.run_server(SocketServer.UDPServer,
@@ -245,9 +260,10 @@ class SocketServerTest(unittest.TestCase):
if HAVE_FORKING:
def test_ForkingUDPServer(self):
- self.run_server(SocketServer.ForkingUDPServer,
- SocketServer.DatagramRequestHandler,
- self.dgram_examine)
+ with simple_subprocess(self):
+ self.run_server(SocketServer.ForkingUDPServer,
+ SocketServer.DatagramRequestHandler,
+ self.dgram_examine)
# Alas, on Linux (at least) recvfrom() doesn't return a meaningful
# client address so this cannot work: