/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/smart/server.py

Merge bzr.dev and resolve conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2006, 2007, 2008 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
18
18
 
19
19
import errno
20
20
import socket
 
21
import sys
21
22
import threading
22
23
 
23
24
from bzrlib.hooks import Hooks
59
60
        self._socket_error = socket_error
60
61
        self._socket_timeout = socket_timeout
61
62
        self._server_socket = socket.socket()
62
 
        self._server_socket.bind((host, port))
 
63
        # SO_REUSERADDR has a different meaning on Windows
 
64
        if sys.platform != 'win32':
 
65
            self._server_socket.setsockopt(socket.SOL_SOCKET,
 
66
                socket.SO_REUSEADDR, 1)
 
67
        try:
 
68
            self._server_socket.bind((host, port))
 
69
        except self._socket_error, message:
 
70
            raise errors.CannotBindAddress(host, port, message)
63
71
        self._sockname = self._server_socket.getsockname()
64
72
        self.port = self._sockname[1]
65
73
        self._server_socket.listen(1)
69
77
        self._stopped = threading.Event()
70
78
        self.root_client_path = root_client_path
71
79
 
72
 
    def serve(self):
 
80
    def serve(self, thread_name_suffix=''):
73
81
        self._should_terminate = False
74
82
        # for hooks we are letting code know that a server has started (and
75
83
        # later stopped).
111
119
                        if e.args[0] != errno.EBADF:
112
120
                            trace.warning("listening socket error: %s", e)
113
121
                    else:
114
 
                        self.serve_conn(conn)
 
122
                        self.serve_conn(conn, thread_name_suffix)
115
123
            except KeyboardInterrupt:
116
124
                # dont log when CTRL-C'd.
117
125
                raise
134
142
        """Return the url of the server"""
135
143
        return "bzr://%s:%d/" % self._sockname
136
144
 
137
 
    def serve_conn(self, conn):
 
145
    def serve_conn(self, conn, thread_name_suffix):
138
146
        # For WIN32, where the timeout value from the listening socket
139
147
        # propogates to the newly accepted socket.
140
148
        conn.setblocking(True)
141
149
        conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
142
150
        handler = SmartServerSocketStreamMedium(
143
151
            conn, self.backing_transport, self.root_client_path)
144
 
        connection_thread = threading.Thread(None, handler.serve, name='smart-server-child')
 
152
        thread_name = 'smart-server-child' + thread_name_suffix
 
153
        connection_thread = threading.Thread(
 
154
            None, handler.serve, name=thread_name)
145
155
        connection_thread.setDaemon(True)
146
156
        connection_thread.start()
147
157
 
148
 
    def start_background_thread(self):
 
158
    def start_background_thread(self, thread_name_suffix=''):
149
159
        self._started.clear()
150
160
        self._server_thread = threading.Thread(None,
151
 
                self.serve,
 
161
                self.serve, args=(thread_name_suffix,),
152
162
                name='server-' + self.get_url())
153
163
        self._server_thread.setDaemon(True)
154
164
        self._server_thread.start()
208
218
    This server is backed by the process's cwd.
209
219
    """
210
220
 
211
 
    def __init__(self):
 
221
    def __init__(self, thread_name_suffix=''):
212
222
        SmartTCPServer.__init__(self, None)
213
223
        self.client_path_extra = None
 
224
        self.thread_name_suffix = thread_name_suffix
214
225
        
215
226
    def get_backing_transport(self, backing_transport_server):
216
227
        """Get a backing transport from a server we are decorating."""
230
241
            `bzr://127.0.0.1:nnnn/`.  Default value is `extra`, so that tests
231
242
            by default will fail unless they do the necessary path translation.
232
243
        """
233
 
        assert client_path_extra.startswith('/')
 
244
        if not client_path_extra.startswith('/'):
 
245
            raise ValueError(client_path_extra)
234
246
        from bzrlib.transport.chroot import ChrootServer
235
247
        if backing_transport_server is None:
236
248
            from bzrlib.transport.local import LocalURLServer
241
253
        self.backing_transport = transport.get_transport(
242
254
            self.chroot_server.get_url())
243
255
        self.root_client_path = self.client_path_extra = client_path_extra
244
 
        self.start_background_thread()
 
256
        self.start_background_thread(self.thread_name_suffix)
245
257
 
246
258
    def tearDown(self):
247
259
        self.stop_background_thread()
249
261
 
250
262
    def get_url(self):
251
263
        url = super(SmartTCPServer_for_testing, self).get_url()
252
 
        assert url.endswith('/')
253
264
        return url[:-1] + self.client_path_extra
254
265
 
255
266
    def get_bogus_url(self):
264
275
        """Get a backing transport from a server we are decorating."""
265
276
        url = 'readonly+' + backing_transport_server.get_url()
266
277
        return transport.get_transport(url)
267