Revision cc4c9b91
b/lib/utils.py | ||
---|---|---|
2486 | 2486 |
assert self.fd, "Lock was closed" |
2487 | 2487 |
assert timeout is None or timeout >= 0, \ |
2488 | 2488 |
"If specified, timeout must be positive" |
2489 |
assert not (flag & fcntl.LOCK_NB), "LOCK_NB must not be set" |
|
2489 | 2490 |
|
2490 |
if timeout is not None: |
|
2491 |
# When a timeout is used, LOCK_NB must always be set |
|
2492 |
if not (timeout is None and blocking): |
|
2491 | 2493 |
flag |= fcntl.LOCK_NB |
2492 |
timeout_end = time.time() + timeout |
|
2493 | 2494 |
|
2494 |
# Blocking doesn't have effect with timeout |
|
2495 |
elif not blocking: |
|
2496 |
flag |= fcntl.LOCK_NB |
|
2497 |
timeout_end = None |
|
2495 |
if timeout is None: |
|
2496 |
self._Lock(self.fd, flag, timeout) |
|
2497 |
else: |
|
2498 |
try: |
|
2499 |
Retry(self._Lock, (0.1, 1.2, 1.0), timeout, |
|
2500 |
args=(self.fd, flag, timeout)) |
|
2501 |
except RetryTimeout: |
|
2502 |
raise errors.LockError(errmsg) |
|
2498 | 2503 |
|
2499 |
# TODO: Convert to utils.Retry |
|
2504 |
@staticmethod |
|
2505 |
def _Lock(fd, flag, timeout): |
|
2506 |
try: |
|
2507 |
fcntl.flock(fd, flag) |
|
2508 |
except IOError, err: |
|
2509 |
if timeout is not None and err.errno == errno.EAGAIN: |
|
2510 |
raise RetryAgain() |
|
2500 | 2511 |
|
2501 |
retry = True |
|
2502 |
while retry: |
|
2503 |
try: |
|
2504 |
fcntl.flock(self.fd, flag) |
|
2505 |
retry = False |
|
2506 |
except IOError, err: |
|
2507 |
if err.errno in (errno.EAGAIN, ): |
|
2508 |
if timeout_end is not None and time.time() < timeout_end: |
|
2509 |
# Wait before trying again |
|
2510 |
time.sleep(max(0.1, min(1.0, timeout))) |
|
2511 |
else: |
|
2512 |
raise errors.LockError(errmsg) |
|
2513 |
else: |
|
2514 |
logging.exception("fcntl.flock failed") |
|
2515 |
raise |
|
2512 |
logging.exception("fcntl.flock failed") |
|
2513 |
raise |
|
2516 | 2514 |
|
2517 | 2515 |
def Exclusive(self, blocking=False, timeout=None): |
2518 | 2516 |
"""Locks the file in exclusive mode. |
Also available in: Unified diff