MCPcopy
hub / github.com/borgbackup/borg / Lock

Class Lock

src/borg/fslocking.py:374–486  ·  view source on GitHub ↗

A Lock for a resource that can be accessed in a shared or exclusive way. Typically, write access to a resource needs an exclusive lock (1 writer, no one is allowed reading) and read access to a resource needs a shared lock (multiple readers are allowed). If possible, try to use

Source from the content-addressed store, hash-verified

372
373
374class Lock:
375 """
376 A Lock for a resource that can be accessed in a shared or exclusive way.
377 Typically, write access to a resource needs an exclusive lock (1 writer,
378 no one is allowed reading) and read access to a resource needs a shared
379 lock (multiple readers are allowed).
380
381 If possible, try to use the contextmanager here like::
382
383 with Lock(...) as lock:
384 ...
385
386 This makes sure the lock is released again if the block is left, no
387 matter how (e.g. if an exception occurred).
388 """
389
390 def __init__(self, path, exclusive=False, sleep=None, timeout=None, id=None):
391 self.path = path
392 self.is_exclusive = exclusive
393 self.sleep = sleep
394 self.timeout = timeout
395 self.id = id or platform.get_process_id()
396 # globally keeping track of shared and exclusive lockers:
397 self._roster = LockRoster(Path(path + ".roster"), id=id)
398 # an exclusive lock, used for:
399 # - holding while doing roster queries / updates
400 # - holding while the Lock itself is exclusive
401 self._lock = ExclusiveLock(str(Path(path + ".exclusive")), id=id, timeout=timeout)
402
403 def __enter__(self):
404 return self.acquire()
405
406 def __exit__(self, *exc):
407 self.release()
408
409 def __repr__(self):
410 return f"<{self.__class__.__name__}: {self.id!r}>"
411
412 def acquire(self, exclusive=None, remove=None, sleep=None):
413 if exclusive is None:
414 exclusive = self.is_exclusive
415 sleep = sleep or self.sleep or 0.2
416 if exclusive:
417 self._wait_for_readers_finishing(remove, sleep)
418 self._roster.modify(EXCLUSIVE, ADD)
419 else:
420 with self._lock:
421 if remove is not None:
422 self._roster.modify(remove, REMOVE)
423 self._roster.modify(SHARED, ADD)
424 self.is_exclusive = exclusive
425 return self
426
427 def _wait_for_readers_finishing(self, remove, sleep):
428 timer = TimeoutTimer(self.timeout, sleep).start()
429 while True:
430 self._lock.acquire()
431 try:

Callers 15

openMethod · 0.70
break_lockMethod · 0.70
break_lockMethod · 0.70
openMethod · 0.70
test_cmMethod · 0.50
test_exclusive_lockMethod · 0.50
test_not_lockedMethod · 0.50
test_break_lockMethod · 0.50
test_migrate_lockMethod · 0.50

Calls

no outgoing calls

Tested by 15

test_cmMethod · 0.40
test_exclusive_lockMethod · 0.40
test_not_lockedMethod · 0.40
test_break_lockMethod · 0.40
test_migrate_lockMethod · 0.40
test_sharedMethod · 0.40
test_exclusiveMethod · 0.40
test_upgradeMethod · 0.40
test_downgradeMethod · 0.40