commit:     0783351b0cb69fc33b984b1fe51e6c642c3bab7d
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Thu Apr 19 16:12:00 2018 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Fri Apr 20 15:49:41 2018 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=0783351b

EbuildBuildDir: add async_unlock method (bug 614108)

Call the existing AsynchronousLock async_unlock method
for the build directory lock, and also handle removal of the
category directory (with async lock/unlock).

Bug: https://bugs.gentoo.org/614108

 pym/_emerge/EbuildBuildDir.py | 46 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/pym/_emerge/EbuildBuildDir.py b/pym/_emerge/EbuildBuildDir.py
index 58905c2f6..1f1385a3b 100644
--- a/pym/_emerge/EbuildBuildDir.py
+++ b/pym/_emerge/EbuildBuildDir.py
@@ -88,6 +88,9 @@ class EbuildBuildDir(SlotObject):
                if self._lock_obj is None:
                        return
 
+               # Keep this legacy implementation until all consumers have 
migrated
+               # to async_unlock, since run_until_complete(self.async_unlock())
+               # would add unwanted event loop recursion here.
                self._lock_obj.unlock()
                self._lock_obj = None
                self.locked = False
@@ -102,6 +105,49 @@ class EbuildBuildDir(SlotObject):
                        finally:
                                catdir_lock.unlock()
 
+       def async_unlock(self):
+               """
+               Release the lock asynchronously. Release notification is 
available
+               via the add_done_callback method of the returned Future 
instance.
+
+               @returns: Future, result is None
+               """
+               result = self.scheduler.create_future()
+
+               def builddir_unlocked(future):
+                       if future.exception() is not None:
+                               result.set_exception(future.exception())
+                       else:
+                               self._lock_obj = None
+                               self.locked = False
+                               self.settings.pop('PORTAGE_BUILDDIR_LOCKED', 
None)
+                               catdir_lock = AsynchronousLock(
+                                       path=self._catdir, 
scheduler=self.scheduler)
+                               catdir_lock.addExitListener(catdir_locked)
+                               catdir_lock.start()
+
+               def catdir_locked(catdir_lock):
+                       if catdir_lock.wait() != os.EX_OK:
+                               result.set_result(None)
+                       else:
+                               try:
+                                       os.rmdir(self._catdir)
+                               except OSError:
+                                       pass
+                               
catdir_lock.async_unlock().add_done_callback(catdir_unlocked)
+
+               def catdir_unlocked(future):
+                       if future.exception() is None:
+                               result.set_result(None)
+                       else:
+                               result.set_exception(future.exception())
+
+               if self._lock_obj is None:
+                       self.scheduler.call_soon(result.set_result, None)
+               else:
+                       
self._lock_obj.async_unlock().add_done_callback(builddir_unlocked)
+               return result
+
        class AlreadyLocked(portage.exception.PortageException):
                pass
 

Reply via email to