~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/lockdir.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-09-26 23:30:56 UTC
  • mfrom: (2044.1.1 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20060926233056-203e713964b2cd51
(Robert Collins) Forward merge from 0.11rc2 NEWS and performance-regression fix.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2006 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
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
 
 
7
#
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
# GNU General Public License for more details.
12
 
 
 
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
96
96
 
97
97
import os
98
98
import time
99
 
from warnings import warn
100
99
from StringIO import StringIO
101
100
 
102
101
import bzrlib.config
106
105
        LockBreakMismatch,
107
106
        LockBroken,
108
107
        LockContention,
109
 
        LockError,
110
108
        LockNotHeld,
111
109
        NoSuchFile,
112
110
        PathError,
116
114
from bzrlib.trace import mutter
117
115
from bzrlib.transport import Transport
118
116
from bzrlib.osutils import rand_chars
119
 
from bzrlib.rio import RioWriter, read_stanza, Stanza
 
117
from bzrlib.rio import read_stanza, Stanza
120
118
 
121
119
# XXX: At the moment there is no consideration of thread safety on LockDir
122
120
# objects.  This should perhaps be updated - e.g. if two threads try to take a
191
189
            raise UnlockableTransport(self.transport)
192
190
        try:
193
191
            tmpname = '%s/pending.%s.tmp' % (self.path, rand_chars(20))
194
 
            self.transport.mkdir(tmpname)
195
 
            sio = StringIO()
196
 
            self._prepare_info(sio)
197
 
            sio.seek(0)
198
 
            # append will create a new file; we use append rather than put
199
 
            # because we don't want to write to a temporary file and rename
200
 
            # into place, because that's going to happen to the whole
201
 
            # directory
202
 
            self.transport.append(tmpname + self.__INFO_NAME, sio)
 
192
            try:
 
193
                self.transport.mkdir(tmpname)
 
194
            except NoSuchFile:
 
195
                # This may raise a FileExists exception
 
196
                # which is okay, it will be caught later and determined
 
197
                # to be a LockContention.
 
198
                self.create(mode=self._dir_modebits)
 
199
                
 
200
                # After creating the lock directory, try again
 
201
                self.transport.mkdir(tmpname)
 
202
 
 
203
            info_bytes = self._prepare_info()
 
204
            # We use put_file_non_atomic because we just created a new unique
 
205
            # directory so we don't have to worry about files existing there.
 
206
            # We'll rename the whole directory into place to get atomic
 
207
            # properties
 
208
            self.transport.put_bytes_non_atomic(tmpname + self.__INFO_NAME,
 
209
                                                info_bytes)
 
210
 
203
211
            self.transport.rename(tmpname, self._held_dir)
204
212
            self._lock_held = True
205
213
            self.confirm()
327
335
        except NoSuchFile, e:
328
336
            return None
329
337
 
330
 
    def _prepare_info(self, outf):
 
338
    def _prepare_info(self):
331
339
        """Write information about a pending lock to a temporary file.
332
340
        """
333
341
        import socket
339
347
                   nonce=self.nonce,
340
348
                   user=config.user_email(),
341
349
                   )
342
 
        RioWriter(outf).write_stanza(s)
 
350
        return s.to_string()
343
351
 
344
352
    def _parse_info(self, info_file):
345
353
        return read_stanza(info_file.readlines()).as_dict()
373
381
        self.attempt_lock()
374
382
 
375
383
    def lock_read(self):
376
 
        """Compatability-mode shared lock.
 
384
        """Compatibility-mode shared lock.
377
385
 
378
386
        LockDir doesn't support shared read-only locks, so this 
379
387
        just pretends that the lock is taken but really does nothing.