'Wait until we acquire this lock.  This method is not safe for
concurrent use.
@type timeout: L{float} or L{int}
@param timeout: the number of seconds after which to time out if the
lock has not been acquired.
@return: a L{Deferred} which will callback when the lock is acquired, or
errback with a L{TimeoutError} after timing out or an
L{AlreadyTryingToLockError} if the L{deferUntilLocked} has already
been called and not successfully locked the file.'

def deferUntilLocked(self, timeout=None):

    if (self._tryLockCall is not None):
        return fail(AlreadyTryingToLockError("deferUntilLocked    isn't    safe    for    concurrent    use."))
    def _cancelLock(reason):
        '\n                                                Cancel    a    L{DeferredFilesystemLock.deferUntilLocked}    call.\n\n                                                @type    reason:    L{failure.Failure}\n                                                @param    reason:    The    reason    why    the    call    is    cancelled.\n                                                '
        self._tryLockCall.cancel()
        self._tryLockCall = None
        if ((self._timeoutCall is not None) and self._timeoutCall.active()):
            self._timeoutCall.cancel()
            self._timeoutCall = None
        if self.lock():
            d.callback(None)
        else:
            d.errback(reason)
    d = Deferred((lambda deferred: _cancelLock(CancelledError())))
    def _tryLock():
        if self.lock():
            if (self._timeoutCall is not None):
                self._timeoutCall.cancel()
                self._timeoutCall = None
            self._tryLockCall = None
            d.callback(None)
        else:
            if ((timeout is not None) and (self._timeoutCall is None)):
                reason = failure.Failure(TimeoutError(('Timed    out    acquiring    lock:    %s    after    %fs' % (self.name, timeout))))
                self._timeoutCall = self._scheduler.callLater(timeout, _cancelLock, reason)
            self._tryLockCall = self._scheduler.callLater(self._interval, _tryLock)
    _tryLock()
    return d
