~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_server.py

Merge previous attempt into current trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008, 2010 Canonical Ltd
 
1
# Copyright (C) 2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
 
17
import socket
 
18
import select
 
19
 
 
20
 
17
21
from bzrlib import (
18
22
    transport,
19
23
    urlutils,
233
237
        super(SmartTCPServer_for_testing, self).__init__(None)
234
238
        self.client_path_extra = None
235
239
        self.thread_name_suffix = thread_name_suffix
 
240
        # We collect the sockets/threads used by the clients so we can
 
241
        # close/join them when shutting down
 
242
        self.clients = []
236
243
 
237
244
    def get_backing_transport(self, backing_transport_server):
238
245
        """Get a backing transport from a server we are decorating."""
265
272
        self.root_client_path = self.client_path_extra = client_path_extra
266
273
        self.start_background_thread(self.thread_name_suffix)
267
274
 
 
275
    def serve_conn(self, conn, thread_name_suffix):
 
276
        conn_thread = super(SmartTCPServer_for_testing, self).serve_conn(
 
277
            conn, thread_name_suffix)
 
278
        self.clients.append((conn, conn_thread))
 
279
        return conn_thread
 
280
 
 
281
    def shutdown_client(self, client_socket):
 
282
        """Properly shutdown a client socket.
 
283
 
 
284
        Under some circumstances (as in bug #383920), we need to force the
 
285
        shutdown as python delays it until gc occur otherwise and the client
 
286
        may hang.
 
287
 
 
288
        This should be called only when no other thread is trying to use the
 
289
        socket.
 
290
        """
 
291
        try:
 
292
            # The request process has been completed, the thread is about to
 
293
            # die, let's shutdown the socket if we can.
 
294
            client_socket.shutdown(socket.SHUT_RDWR)
 
295
        except (socket.error, select.error), e:
 
296
            if e[0] in (errno.EBADF, errno.ENOTCONN):
 
297
                # Right, the socket is already down
 
298
                pass
 
299
            else:
 
300
                raise
 
301
 
268
302
    def stop_server(self):
269
303
        self.stop_background_thread()
 
304
        # Let's close all our pending clients too
 
305
        for sock, thread in self.clients:
 
306
            self.shutdown_client(sock)
 
307
            thread.join()
 
308
            del thread
 
309
        self.clients = []
270
310
        self.chroot_server.stop_server()
271
311
 
272
312
    def get_url(self):