summaryrefslogtreecommitdiffstats
path: root/pym/portage/dbapi/vartree.py
diff options
context:
space:
mode:
Diffstat (limited to 'pym/portage/dbapi/vartree.py')
-rw-r--r--pym/portage/dbapi/vartree.py34
1 files changed, 32 insertions, 2 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