mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
Allow to give lock to multiple processes (#154)
* Check also son_of_locked for self * Check again that we're son of locked when trying to acquire lock * Support having multiple PIDs in lock file.. * Fix/improve son_of_lock detection
This commit is contained in:
parent
ca580bbcfb
commit
0665cb4dd5
1 changed files with 26 additions and 17 deletions
|
@ -442,16 +442,21 @@ class MoulinetteLock(object):
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
lock_pid = self._lock_PID()
|
|
||||||
|
|
||||||
if lock_pid is None:
|
lock_pids = self._lock_PIDs()
|
||||||
|
|
||||||
|
if self._is_son_of(lock_pids):
|
||||||
|
return
|
||||||
|
|
||||||
|
if lock_pids == []:
|
||||||
self._lock()
|
self._lock()
|
||||||
break
|
break
|
||||||
elif not self._stale_checked:
|
elif not self._stale_checked:
|
||||||
self._stale_checked = True
|
self._stale_checked = True
|
||||||
# Delete stale lock file
|
# Check locked process still exist and take lock if it doesnt
|
||||||
if not lock_pid or not os.path.exists(
|
# FIXME : what do in the context of multiple locks :|
|
||||||
os.path.join('/proc', lock_pid, 'exe')):
|
first_lock = lock_pids[0]
|
||||||
|
if not os.path.exists(os.path.join('/proc', str(first_lock), 'exe')):
|
||||||
logger.debug('stale lock file found')
|
logger.debug('stale lock file found')
|
||||||
self._lock()
|
self._lock()
|
||||||
break
|
break
|
||||||
|
@ -486,28 +491,32 @@ class MoulinetteLock(object):
|
||||||
moulinette.m18n.g('permission_denied'),
|
moulinette.m18n.g('permission_denied'),
|
||||||
moulinette.m18n.g('root_required')))
|
moulinette.m18n.g('root_required')))
|
||||||
|
|
||||||
def _lock_PID(self):
|
def _lock_PIDs(self):
|
||||||
|
|
||||||
if not os.path.isfile(self._lockfile):
|
if not os.path.isfile(self._lockfile):
|
||||||
return None
|
return []
|
||||||
|
|
||||||
with open(self._lockfile) as f:
|
with open(self._lockfile) as f:
|
||||||
lock_pid = f.read().strip()
|
lock_pids = f.read().strip().split('\n')
|
||||||
|
|
||||||
return lock_pid
|
# Make sure to convert those pids to integers
|
||||||
|
lock_pids = [ int(pid) for pid in lock_pids ]
|
||||||
|
|
||||||
def _is_son_of_locked(self):
|
return lock_pids
|
||||||
lock_pid = self._lock_PID()
|
|
||||||
|
|
||||||
if lock_pid is None:
|
def _is_son_of(self, lock_pids):
|
||||||
|
|
||||||
|
if lock_pids == []:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Start with self
|
||||||
parent = psutil.Process()
|
parent = psutil.Process()
|
||||||
# While this is not the very first process
|
|
||||||
while parent.parent() is not None:
|
# While there is a parent... (e.g. init has no parent)
|
||||||
# If parent PID is the lock, the yes! we are a son of the process
|
while parent is not None:
|
||||||
|
# If parent PID is the lock, then yes! we are a son of the process
|
||||||
# with the lock...
|
# with the lock...
|
||||||
if parent.ppid() == int(lock_pid):
|
if parent.pid in lock_pids:
|
||||||
return True
|
return True
|
||||||
# Otherwise, try 'next' parent
|
# Otherwise, try 'next' parent
|
||||||
parent = parent.parent()
|
parent = parent.parent()
|
||||||
|
@ -515,7 +524,7 @@ class MoulinetteLock(object):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
if not self._locked and not self._is_son_of_locked():
|
if not self._locked:
|
||||||
self.acquire()
|
self.acquire()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue