IP : 18.223.134.71Hostname : server86.web-hosting.comKernel : Linux server86.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64Disable Function : None :) OS : Linux
PATH:
/
home/
./
./
../
../
lib64/
gawk/
../
python2.7/
Demo/
pdist/
cvslock.py/
/
"""CVS locking algorithm.
CVS locking strategy ====================
As reverse engineered from the CVS 1.3 sources (file lock.c):
- Locking is done on a per repository basis (but a process can hold write locks for multiple directories); all lock files are placed in the repository and have names beginning with "#cvs.".
- Before even attempting to lock, a file "#cvs.tfl.<pid>" is created (and removed again), to test that we can write the repository. [The algorithm can still be fooled (1) if the repository's mode is changed while attempting to lock; (2) if this file exists and is writable but the directory is not.]
- While creating the actual read/write lock files (which may exist for a long time), a "meta-lock" is held. The meta-lock is a directory named "#cvs.lock" in the repository. The meta-lock is also held while a write lock is held.
- To set a read lock:
- acquire the meta-lock - create the file "#cvs.rfl.<pid>" - release the meta-lock
- To set a write lock:
- acquire the meta-lock - check that there are no files called "#cvs.rfl.*" - if there are, release the meta-lock, sleep, try again - create the file "#cvs.wfl.<pid>"
- To release a write lock:
- remove the file "#cvs.wfl.<pid>" - rmdir the meta-lock
- To release a read lock:
- remove the file "#cvs.rfl.<pid>"
Additional notes ----------------
- A process should read-lock at most one repository at a time.
- A process may write-lock as many repositories as it wishes (to avoid deadlocks, I presume it should always lock them top-down in the directory hierarchy).
- A process should make sure it removes all its lock files and directories when it crashes.
- Limitation: one user id should not be committing files into the same repository at the same time.
Turn this into Python code --------------------------
rl = ReadLock(repository, waittime)
wl = WriteLock(repository, waittime)
list = MultipleWriteLock([repository1, repository2, ...], waittime)
"""
import os import time import stat import pwd
# Default wait time DELAY = 10
# XXX This should be the same on all Unix versions EEXIST = 17
# Files used for locking (must match cvs.h in the CVS sources) CVSLCK = "#cvs.lck" CVSRFL = "#cvs.rfl." CVSWFL = "#cvs.wfl."
def __init__(self, repository, delay = DELAY): Lock.__init__(self, repository, delay) ok = 0 try: self.setlockdir() self.lockfile = self.cvsrfl fp = open(self.lockfile, 'w') fp.close() ok = 1 finally: if not ok: self.unlockfile() self.unlockdir()
class WriteLock(Lock):
def __init__(self, repository, delay = DELAY): Lock.__init__(self, repository, delay) self.setlockdir() while 1: uid = self.readers_exist() if not uid: break self.unlockdir() self.sleep(uid) self.lockfile = self.cvswfl fp = open(self.lockfile, 'w') fp.close()
def readers_exist(self): n = len(CVSRFL) for name in os.listdir(self.repository): if name[:n] == CVSRFL: try: st = os.stat(self.join(name)) except os.error: continue return st return None
def MultipleWriteLock(repositories, delay = DELAY): while 1: locks = [] for r in repositories: try: locks.append(WriteLock(r, 0)) except Locked, instance: del locks break else: break sleep(instance.msg, r, delay) return list