summaryrefslogtreecommitdiff
path: root/pym
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2013-06-08 04:08:47 -0700
committerZac Medico <zmedico@gentoo.org>2013-06-08 04:08:47 -0700
commit1c9627e3749553a792de609c7931d17930738aed (patch)
tree99aeb781960b00f7e280a2b1dd009b31ecb98b97 /pym
parentporttree._dummy_list: fix infinite recursion (diff)
downloadportage-1c9627e3749553a792de609c7931d17930738aed.tar.gz
portage-1c9627e3749553a792de609c7931d17930738aed.tar.bz2
portage-1c9627e3749553a792de609c7931d17930738aed.zip
close_portdbapi_caches: portage.db atexit hook
The python interpreter does _not_ guarantee that destructors are called for objects that remain when the interpreter exits, so we use an atexit hook to call destructors for any global portdbapi instances that may have been constructed.
Diffstat (limited to 'pym')
-rw-r--r--pym/portage/dbapi/porttree.py37
-rw-r--r--pym/portage/tests/resolver/ResolverPlayground.py3
2 files changed, 36 insertions, 4 deletions
diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py
index b106de779..fc3fc0396 100644
--- a/pym/portage/dbapi/porttree.py
+++ b/pym/portage/dbapi/porttree.py
@@ -53,6 +53,39 @@ if sys.hexversion >= 0x3000000:
basestring = str
long = int
+def close_portdbapi_caches():
+ # The python interpreter does _not_ guarantee that destructors are
+ # called for objects that remain when the interpreter exits, so we
+ # use an atexit hook to call destructors for any global portdbapi
+ # instances that may have been constructed.
+ try:
+ portage._legacy_globals_constructed
+ except AttributeError:
+ pass
+ else:
+ if "db" in portage._legacy_globals_constructed:
+ try:
+ db = portage.db
+ except AttributeError:
+ pass
+ else:
+ if isinstance(db, dict):
+ for x in db.values():
+ try:
+ if "porttree" in x.lazy_items:
+ continue
+ except (AttributeError, TypeError):
+ continue
+ try:
+ x = x.pop("porttree").dbapi
+ except (AttributeError, KeyError):
+ continue
+ if not isinstance(x, portdbapi):
+ continue
+ x.close_caches()
+
+portage.process.atexit_register(close_portdbapi_caches)
+
# It used to be necessary for API consumers to remove portdbapi instances
# from portdbapi_instances, in order to avoid having accumulated instances
# consume memory. Now, portdbapi_instances is just an empty dummy list, so
@@ -67,10 +100,6 @@ class _dummy_list(list):
except ValueError:
pass
-def close_portdbapi_caches():
- # Since portdbapi_instances is a dummy list, there's nothing to do here.
- pass
-
class portdbapi(dbapi):
"""this tree will scan a portage directory located at root (passed to init)"""
portdbapi_instances = _dummy_list()
diff --git a/pym/portage/tests/resolver/ResolverPlayground.py b/pym/portage/tests/resolver/ResolverPlayground.py
index 15ef95da7..bff4512fe 100644
--- a/pym/portage/tests/resolver/ResolverPlayground.py
+++ b/pym/portage/tests/resolver/ResolverPlayground.py
@@ -544,6 +544,9 @@ class ResolverPlayground(object):
return
def cleanup(self):
+ for eroot in self.trees:
+ portdb = self.trees[eroot]["porttree"].dbapi
+ portdb.close_caches()
if self.debug:
print("\nEROOT=%s" % self.eroot)
else: