Rev 4732: Don't use socket.shutdown() to stop http servers in http://bazaar.launchpad.net/~vila/bzr/integration
Vincent Ladeuil
v.ladeuil+lp at free.fr
Wed Oct 7 16:06:35 BST 2009
At http://bazaar.launchpad.net/~vila/bzr/integration
------------------------------------------------------------
revno: 4732 [merge]
revision-id: v.ladeuil+lp at free.fr-20091007150623-6mcdxxyy6yefjcio
parent: pqm at pqm.ubuntu.com-20091006204548-bjnc3z4k256ppimz
parent: v.ladeuil+lp at free.fr-20091007102404-tqyhafwp5ur19kz0
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: integration
timestamp: Wed 2009-10-07 17:06:23 +0200
message:
Don't use socket.shutdown() to stop http servers
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/tests/http_server.py httpserver.py-20061012142527-m1yxdj1xazsf8d7s-1
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2009-10-06 20:45:48 +0000
+++ b/NEWS 2009-10-07 10:24:04 +0000
@@ -203,6 +203,9 @@
Testing
*******
+* HTTP test servers will leak less threads (and sockets) and will not hang on
+ AIX anymore. (Vincent Ladeuil, #405745)
+
* Passing ``--lsprof-tests -v`` to bzr selftest will cause lsprof output to
be output for every test. Note that this is very verbose! (Robert Collins)
=== modified file 'bzrlib/tests/http_server.py'
--- a/bzrlib/tests/http_server.py 2009-07-08 15:24:31 +0000
+++ b/bzrlib/tests/http_server.py 2009-10-07 10:24:04 +0000
@@ -324,34 +324,17 @@
Since the server may be (surely is, even) in a blocking listen, we
shutdown its socket before closing it.
"""
- # Note that is this executed as part of the implicit tear down in the
- # main thread while the server runs in its own thread. The clean way
- # to tear down the server is to instruct him to stop accepting
- # connections and wait for the current connection(s) to end
- # naturally. To end the connection naturally, the http transports
- # should close their socket when they do not need to talk to the
- # server anymore. This happens naturally during the garbage collection
- # phase of the test transport objetcs (the server clients), so we
- # don't have to worry about them. So, for the server, we must tear
- # down here, from the main thread, when the test have ended. Note
- # that since the server is in a blocking operation and since python
- # use select internally, shutting down the socket is reliable and
- # relatively clean.
+ # The server is listening for a last connection, let's give it:
try:
- self.socket.shutdown(socket.SHUT_RDWR)
+ fake_conn = socket.create_connection(self.server_address)
+ fake_conn.close()
except socket.error, e:
- # WSAENOTCONN (10057) 'Socket is not connected' is harmless on
- # windows (occurs before the first connection attempt
- # vila--20071230)
-
- # 'Socket is not connected' can also occur on OSX, with a
- # "regular" ENOTCONN (when something went wrong during test case
- # setup leading to self.setUp() *not* being called but
- # self.tearDown() still being called -- vila20081106
- if not len(e.args) or e.args[0] not in (errno.ENOTCONN, 10057):
- raise
- # Let the server properly close the socket
- self.server_close()
+ # But ignore connection errors as the point is to unblock the
+ # server thread, it may happen that it's not blocked or even not
+ # started (when something went wrong during test case setup
+ # leading to self.setUp() *not* being called but self.tearDown()
+ # still being called)
+ pass
class TestingHTTPServer(SocketServer.TCPServer, TestingHTTPServerMixin):
@@ -501,6 +484,9 @@
pass
else:
raise
+ if self._httpd is not None:
+ # Let the server properly close the listening socket
+ self._httpd.server_close()
def _get_remote_url(self, path):
path_parts = path.split(os.path.sep)
@@ -527,10 +513,10 @@
"""
# XXX: TODO: make the server back onto vfs_server rather than local
# disk.
- if not (backing_transport_server is None or \
- isinstance(backing_transport_server, local.LocalURLServer)):
+ if not (backing_transport_server is None
+ or isinstance(backing_transport_server, local.LocalURLServer)):
raise AssertionError(
- "HTTPServer currently assumes local transport, got %s" % \
+ "HTTPServer currently assumes local transport, got %s" %
backing_transport_server)
self._home_dir = os.getcwdu()
self._local_path_parts = self._home_dir.split(os.path.sep)
@@ -556,11 +542,9 @@
def tearDown(self):
"""See bzrlib.transport.Server.tearDown."""
+ self._http_running = False
self._httpd.tearDown()
- self._http_running = False
- # We don't need to 'self._http_thread.join()' here since the thread is
- # a daemonic one and will be garbage collected anyway. Joining just
- # slows us down for no added benefit.
+ self._http_thread.join()
def get_url(self):
"""See bzrlib.transport.Server.get_url."""
More information about the bazaar-commits
mailing list