commit:     02922cb3a7eb72e9bf4cec9e30b35aa4adaa51c8
Author:     Zac Medico <zachary.medico <AT> sony <DOT> com>
AuthorDate: Tue Feb 19 23:59:35 2019 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Wed Feb 20 00:38:09 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=02922cb3

lockfile: use loop instead of recursion

Copyright: Sony Interactive Entertainment Inc.
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/portage/locks.py | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/lib/portage/locks.py b/lib/portage/locks.py
index a23d5cb56..fff27e55e 100644
--- a/lib/portage/locks.py
+++ b/lib/portage/locks.py
@@ -107,7 +107,34 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0,
        If wantnewlockfile is True then this creates a lockfile in the parent
        directory as the file: '.' + basename + '.portage_lockfile'.
        """
+       lock = None
+       while lock is None:
+               lock = _lockfile_iteration(mypath, 
wantnewlockfile=wantnewlockfile,
+                       unlinkfile=unlinkfile, waiting_msg=waiting_msg, 
flags=flags)
+               if lock is None:
+                       writemsg(_("lockfile removed by previous lock holder, 
retrying\n"), 1)
+       return lock
 
+
+def _lockfile_iteration(mypath, wantnewlockfile=False, unlinkfile=False,
+       waiting_msg=None, flags=0):
+       """
+       Acquire a lock on mypath, without retry. Return None if the lockfile
+       was removed by previous lock holder (caller must retry).
+
+       @param mypath: lock file path
+       @type mypath: str
+       @param wantnewlockfile: use a separate new lock file
+       @type wantnewlockfile: bool
+       @param unlinkfile: remove lock file prior to unlock
+       @type unlinkfile: bool
+       @param waiting_msg: message to show before blocking
+       @type waiting_msg: str
+       @param flags: lock flags (only supports os.O_NONBLOCK)
+       @type flags: int
+       @rtype: bool
+       @return: unlockfile tuple on success, None if retry is needed
+       """
        if not mypath:
                raise InvalidData(_("Empty path given"))
 
@@ -274,12 +301,9 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0,
                
        if isinstance(lockfilename, basestring) and \
                myfd != HARDLINK_FD and unlinkfile and 
_lockfile_was_removed(myfd, lockfilename):
-               # The file was deleted on us... Keep trying to make one...
+               # Removed by previous lock holder... Caller will retry...
                os.close(myfd)
-               writemsg(_("lockfile recurse\n"), 1)
-               lockfilename, myfd, unlinkfile, locking_method = lockfile(
-                       mypath, wantnewlockfile=wantnewlockfile, 
unlinkfile=unlinkfile,
-                       waiting_msg=waiting_msg, flags=flags)
+               return None
 
        if myfd != HARDLINK_FD:
 

Reply via email to