Rev 4735: No more leaks in http tests. in file:///home/vila/src/bzr/bugs/392127-thread-leak/

Vincent Ladeuil v.ladeuil+lp at free.fr
Wed Oct 7 16:17:50 BST 2009


At file:///home/vila/src/bzr/bugs/392127-thread-leak/

------------------------------------------------------------
revno: 4735
revision-id: v.ladeuil+lp at free.fr-20091007151748-lcg3ehht39963izr
parent: v.ladeuil+lp at free.fr-20091007145554-j0njl74ji5o5v6cx
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 392127-thread-leak
timestamp: Wed 2009-10-07 17:17:48 +0200
message:
  No more leaks in http tests.
  
  * bzrlib/tests/test_http.py:
  (RecordingServer.setUp, RecordingServer.TearDown): Reclaim leaked
  thread by forcing a connection if none has been issued and
  modifying the server to cope with it. Also delete the dead thread.
  
  * bzrlib/tests/http_server.py:
  (TestingThreadingHTTPServer.shutdown, HttpServer.tearDown): Delete
  dead thread.
-------------- next part --------------
=== modified file 'bzrlib/tests/http_server.py'
--- a/bzrlib/tests/http_server.py	2009-10-07 14:55:54 +0000
+++ b/bzrlib/tests/http_server.py	2009-10-07 15:17:48 +0000
@@ -438,6 +438,7 @@
         for c, t in self.clients:
             self.shutdown_client(c)
             t.join()
+            del t
 
 
 class HttpServer(transport.Server):
@@ -586,6 +587,8 @@
         self._http_running = False
         self._httpd.shutdown()
         self._http_thread.join()
+        del self._http_thread
+        self._http_thread = None
 
     def get_url(self):
         """See bzrlib.transport.Server.get_url."""

=== modified file 'bzrlib/tests/test_http.py'
--- a/bzrlib/tests/test_http.py	2009-10-07 14:55:54 +0000
+++ b/bzrlib/tests/test_http.py	2009-10-07 15:17:48 +0000
@@ -228,22 +228,25 @@
         self._thread = threading.Thread(target=self._accept_read_and_reply)
         self._thread.setDaemon(True)
         self._thread.start()
-        self._ready.wait(5)
+        self._ready.wait()
 
     def _accept_read_and_reply(self):
         self._sock.listen(1)
+        self._sock.settimeout(5)
         self._ready.set()
-        self._sock.settimeout(5)
         try:
             conn, address = self._sock.accept()
             # On win32, the accepted connection will be non-blocking to start
             # with because we're using settimeout.
             conn.setblocking(True)
-            while not self.received_bytes.endswith(self._expect_body_tail):
-                self.received_bytes += conn.recv(4096)
-            conn.sendall('HTTP/1.1 200 OK\r\n')
+            if self._expect_body_tail is not None:
+                while not self.received_bytes.endswith(self._expect_body_tail):
+                    self.received_bytes += conn.recv(4096)
+                conn.sendall('HTTP/1.1 200 OK\r\n')
         except socket.timeout:
             # Make sure the client isn't stuck waiting for us to e.g. accept.
+            pass
+        try:
             self._sock.close()
         except socket.error:
             # The client may have already closed the socket.
@@ -251,12 +254,18 @@
 
     def tearDown(self):
         try:
-            self._sock.close()
+            # Issue a fake connection to wake up the server and allow it to
+            # finish quickly
+            fake_conn = socket.create_connection((self.host, self.port))
+            fake_conn.close()
         except socket.error:
             # We might have already closed it.  We don't care.
             pass
         self.host = None
         self.port = None
+        self._thread.join()
+        del self._thread
+        self.thread = None
 
 
 class TestAuthHeader(tests.TestCase):



More information about the bazaar-commits mailing list