[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gentoo-portage-dev
Subject:    [gentoo-portage-dev] [PATCH 1/2] EbuildBuildDir: add async_unlock method (bug 614108)
From:       Zac Medico <zmedico () gentoo ! org>
Date:       2018-04-19 17:02:43
Message-ID: 20180419170244.14451-2-zmedico () gentoo ! org
[Download RAW message or body]

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

Bug: https://bugs.gentoo.org/614108
---
 pym/_emerge/EbuildBuildDir.py | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/pym/_emerge/EbuildBuildDir.py b/pym/_emerge/EbuildBuildDir.py
index 58905c2f6..da7128689 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,46 @@ 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.start()
+				catdir_lock.addExitListener(catdir_locked)
+
+		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())
+
+		self._lock_obj.async_unlock().add_done_callback(builddir_unlocked)
+		return result
+
 	class AlreadyLocked(portage.exception.PortageException):
 		pass
 
-- 
2.13.6


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic