diff options
author | Christian Heimes <christian@cheimes.de> | 2008-02-28 20:02:27 (GMT) |
---|---|---|
committer | Christian Heimes <christian@cheimes.de> | 2008-02-28 20:02:27 (GMT) |
commit | 70e7ea23f18aacc31f429787645ff8c074c0ad86 (patch) | |
tree | beb83e14c2f9fdd729914234d9979b50a70718c3 /Lib | |
parent | 9e7f1d2e965400edcb2c0cb7fee625ef2b595eb5 (diff) | |
download | cpython-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.py | 7 | ||||
-rw-r--r-- | Lib/SocketServer.py | 30 | ||||
-rw-r--r-- | Lib/test/test_socketserver.py | 36 |
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: |