From 646c21b911ca2d14fb0f8489ff22e05fe9c4199a Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sat, 7 May 2011 19:57:29 -0700 Subject: Add vardbapi reentrant lock/unlock methods. --- pym/portage/dbapi/vartree.py | 54 +++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 16 deletions(-) (limited to 'pym') diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 7f9fb9936..bc9916e31 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -131,6 +131,10 @@ class vardbapi(dbapi): DeprecationWarning, stacklevel=2) self._eroot = settings['EROOT'] + self._dbroot = self._eroot + VDB_PATH + self._lock = None + self._lock_count = 0 + if vartree is None: vartree = portage.db[self.root]["vartree"] self.vartree = vartree @@ -167,6 +171,38 @@ class vardbapi(dbapi): rValue = _os.path.join(rValue, filename) return rValue + def lock(self): + """ + Acquire a reentrant lock, blocking, for cooperation with concurrent + processes. State is inherited by subprocesses, allowing subprocesses + to reenter a lock that was acquired by a parent process. However, + a lock can be released only by the same process that acquired it. + """ + if self._lock_count: + self._lock_count += 1 + else: + if self._lock is not None: + raise AssertionError("already locked") + # At least the parent needs to exist for the lock file. + ensure_dirs(self._dbroot) + self._lock = lockdir(self._dbroot) + self._lock_count += 1 + + def unlock(self): + """ + Release a lock, decrementing the recursion level. Each unlock() call + must be matched with a prior lock() call, or else an AssertionError + will be raised if unlock() is called while not locked. + """ + if self._lock_count > 1: + self._lock_count -= 1 + else: + if self._lock is None: + raise AssertionError("not locked") + self._lock_count = 0 + unlockdir(self._lock) + self._lock = None + def _bump_mtime(self, cpv): """ This is called before an after any modifications, so that consumers @@ -1226,10 +1262,6 @@ class dblink(object): self.dbpkgdir = self.dbcatdir+"/"+pkg self.dbtmpdir = self.dbcatdir+"/-MERGING-"+pkg self.dbdir = self.dbpkgdir - - self._lock_vdb = None - self._lock_vdb_count = 0 - self.settings = mysettings self._verbose = self.settings.get("PORTAGE_VERBOSE") == "1" @@ -1269,20 +1301,10 @@ class dblink(object): self._get_protect_obj().updateprotect() def lockdb(self): - if self._lock_vdb_count: - self._lock_vdb_count += 1 - else: - # At least the parent needs to exist for the lock file. - ensure_dirs(self.dbroot) - self._lock_vdb = lockdir(self.dbroot) + self.vartree.dbapi.lock() def unlockdb(self): - if self._lock_vdb_count > 1: - self._lock_vdb_count -= 1 - else: - self._lock_vdb_count = 0 - unlockdir(self._lock_vdb) - self._lock_vdb = None + self.vartree.dbapi.unlock() def getpath(self): "return path to location of db information (for >>> informational display)" -- cgit v1.2.3-1-g7c22