diff options
author | Zac Medico <zmedico@gentoo.org> | 2010-12-26 13:22:38 -0800 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2010-12-26 13:22:38 -0800 |
commit | 460fa368db599a21769e1be267d19cd3a5bd9572 (patch) | |
tree | 491da0d7bfedb0c8c3301530e5e1b81e49661a5f | |
parent | 7b8051236f5faf908d8cbb35980925523513bd87 (diff) | |
download | portage-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.py | 34 |
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. |