summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2010-12-26 13:22:38 -0800
committerZac Medico <zmedico@gentoo.org>2010-12-26 13:22:38 -0800
commit460fa368db599a21769e1be267d19cd3a5bd9572 (patch)
tree491da0d7bfedb0c8c3301530e5e1b81e49661a5f
parent7b8051236f5faf908d8cbb35980925523513bd87 (diff)
downloadportage-460fa368db599a21769e1be267d19cd3a5bd9572.tar.gz
portage-460fa368db599a21769e1be267d19cd3a5bd9572.tar.bz2
portage-460fa368db599a21769e1be267d19cd3a5bd9572.zip
anydbm: use gdbm "u" flag for concurrent writers
This will fix bug #53607.
-rw-r--r--pym/portage/cache/anydbm.py34
1 files changed, 30 insertions, 4 deletions
diff --git a/pym/portage/cache/anydbm.py b/pym/portage/cache/anydbm.py
index 1cf3775eb..1d56b1458 100644
--- a/pym/portage/cache/anydbm.py
+++ b/pym/portage/cache/anydbm.py
@@ -9,6 +9,20 @@ try:
except ImportError:
# python 3.x
import dbm as anydbm_module
+
+try:
+ import dbm.gnu as gdbm
+except ImportError:
+ try:
+ import gdbm
+ except ImportError:
+ gdbm = None
+
+try:
+ from dbm import whichdb
+except ImportError:
+ from whichdb import whichdb
+
try:
import cPickle as pickle
except ImportError:
@@ -35,11 +49,15 @@ class database(fs_template.FsBased):
self._db_path = os.path.join(self.location, fs_template.gen_label(self.location, self.label)+default_db)
self.__db = None
+ mode = "w"
+ if whichdb(self._db_path) in ("dbm.gnu", "gdbm"):
+ # Allow multiple concurrent writers (see bug #53607).
+ mode += "u"
try:
# dbm.open() will not work with bytes in python-3.1:
# TypeError: can't concat bytes to str
self.__db = anydbm_module.open(self._db_path,
- 'w', self._perms)
+ mode, self._perms)
except anydbm_module.error:
# XXX handle this at some point
try:
@@ -53,14 +71,22 @@ class database(fs_template.FsBased):
if self.__db == None:
# dbm.open() will not work with bytes in python-3.1:
# TypeError: can't concat bytes to str
- self.__db = anydbm_module.open(self._db_path,
- 'c', self._perms)
+ if gdbm is None:
+ self.__db = anydbm_module.open(self._db_path,
+ "c", self._perms)
+ else:
+ # Prefer gdbm type if available, since it allows
+ # multiple concurrent writers (see bug #53607).
+ self.__db = gdbm.open(self._db_path,
+ "cu", self._perms)
except anydbm_module.error as e:
raise cache_errors.InitializationError(self.__class__, e)
self._ensure_access(self._db_path)
def iteritems(self):
- return iter(self.__db.items())
+ # dbm doesn't implement items()
+ for k in self.__db.keys():
+ yield (k, self[k])
def _getitem(self, cpv):
# we override getitem because it's just a cpickling of the data handed in.