diff options
author | Zac Medico <zmedico@gentoo.org> | 2010-09-13 00:23:34 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2010-09-13 00:23:34 -0700 |
commit | 58b184b441ff53c46cbb38eb695933d60c6624ad (patch) | |
tree | 21cbeaaf4a869b0f7ffba07cf5ae07d42695c1dd | |
parent | 46243c16a2538e494d5b98e6f0d3ec17ad80d1b7 (diff) | |
download | portage-58b184b441ff53c46cbb38eb695933d60c6624ad.tar.gz portage-58b184b441ff53c46cbb38eb695933d60c6624ad.tar.bz2 portage-58b184b441ff53c46cbb38eb695933d60c6624ad.zip |
Bug #336142 - Add support for using a thread to wait for locks inside
dblink.lockdb() so that the scheduler can concurrently service ipc
calls in the main thread.
-rw-r--r-- | pym/portage/dbapi/vartree.py | 34 | ||||
-rw-r--r-- | pym/portage/locks.py | 4 |
2 files changed, 34 insertions, 4 deletions
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index fddb4326c..19ebaaa76 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -37,7 +37,7 @@ from portage.const import _ENABLE_DYN_LINK_MAP, _ENABLE_PRESERVE_LIBS from portage.dbapi import dbapi from portage.exception import CommandNotFound, \ InvalidData, InvalidPackageName, \ - FileNotFound, PermissionDenied, UnsupportedAPIException + FileNotFound, PermissionDenied, TryAgain, UnsupportedAPIException from portage.localization import _ from portage.util.movefile import movefile @@ -62,6 +62,10 @@ import os as _os import stat import sys import tempfile +try: + import threading +except ImportError: + import dummy_threading as threading import time import warnings @@ -1276,13 +1280,39 @@ class dblink(object): raise AssertionError("Lock already held.") # At least the parent needs to exist for the lock file. ensure_dirs(self.dbroot) - self._lock_vdb = lockdir(self.dbroot) + if self._scheduler is None: + self._lock_vdb = lockdir(self.dbroot) + else: + try: + self._lock_vdb = lockdir(self.dbroot, flags=os.O_NONBLOCK) + except TryAgain: + self._lockdb_rlock = threading.RLock() + lockdb_thread = threading.Thread( + target=self._lockdb_thread) + lockdb_thread.start() + if not self._lockdb_have_lock(): + self._scheduler.schedule( + condition=self._lockdb_have_lock) + lockdb_thread.join() + self._lockdb_rlock = None def unlockdb(self): if self._lock_vdb: unlockdir(self._lock_vdb) self._lock_vdb = None + def _lockdb_thread(self): + lock_vdb = lockdir(self.dbroot) + self._lockdb_rlock.acquire() + self._lock_vdb = lock_vdb + self._lockdb_rlock.release() + + def _lockdb_have_lock(self): + self._lockdb_rlock.acquire() + rval = self._lock_vdb is not None + self._lockdb_rlock.release() + return rval + def getpath(self): "return path to location of db information (for >>> informational display)" return self.dbdir diff --git a/pym/portage/locks.py b/pym/portage/locks.py index ed20e30ca..00a50b818 100644 --- a/pym/portage/locks.py +++ b/pym/portage/locks.py @@ -30,8 +30,8 @@ HARDLINK_FD = -2 # so that it doesn't interfere with the status display. _quiet = False -def lockdir(mydir): - return lockfile(mydir,wantnewlockfile=1) +def lockdir(mydir, flags=0): + return lockfile(mydir, wantnewlockfile=1, flags=flags) def unlockdir(mylock): return unlockfile(mylock) |