From dcdef4527234489e0483459712dcef585445301b Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Fri, 26 Jun 2009 21:32:01 +0000 Subject: Bug #275532 - In action_depclean(), free memory from the dep calculation before calling unmerge(). svn path=/main/trunk/; revision=13699 --- pym/_emerge/actions.py | 101 ++++++++++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 39 deletions(-) (limited to 'pym/_emerge') diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py index 0915f8341..88c7dd4e9 100644 --- a/pym/_emerge/actions.py +++ b/pym/_emerge/actions.py @@ -558,7 +558,6 @@ def action_depclean(settings, trees, ldpath_mtimes, # that should have been pulled into the graph. On the other hand, it's # relatively safe to ignore missing deps when only asked to remove # specific packages. - allow_missing_deps = len(myfiles) > 0 msg = [] msg.append("Always study the list of packages to be cleaned for any obvious\n") @@ -580,6 +579,60 @@ def action_depclean(settings, trees, ldpath_mtimes, for x in msg: portage.writemsg_stdout(colorize("WARN", " * ") + x) + root_config = trees[settings['ROOT']]['root_config'] + vardb = root_config.trees['vartree'].dbapi + + args_set = InternalPackageSet() + if myfiles: + args_set.update(myfiles) + matched_packages = False + for x in args_set: + if vardb.match(x): + matched_packages = True + break + if not matched_packages: + writemsg_level(">>> No packages selected for removal by %s\n" % \ + action) + return 0 + + # The calculation is done in a separate function so that depgraph + # references go out of scope and the corresponding memory + # is freed before we call unmerge(). + rval, cleanlist, ordered, req_pkg_count = \ + calc_depclean(settings, trees, ldpath_mtimes, + myopts, action, args_set, spinner) + + import gc + gc.collect() + + if rval != os.EX_OK: + return rval + + if cleanlist: + unmerge(root_config, myopts, "unmerge", + cleanlist, ldpath_mtimes, ordered=ordered) + + if action == "prune": + return + + if not cleanlist and "--quiet" in myopts: + return + + print "Packages installed: " + str(len(vardb.cpv_all())) + print "Packages in world: " + \ + str(len(root_config.sets["world"].getAtoms())) + print "Packages in system: " + \ + str(len(root_config.sets["system"].getAtoms())) + print "Required packages: "+str(req_pkg_count) + if "--pretend" in myopts: + print "Number to remove: "+str(len(cleanlist)) + else: + print "Number removed: "+str(len(cleanlist)) + +def calc_depclean(settings, trees, ldpath_mtimes, + myopts, action, args_set, spinner): + allow_missing_deps = bool(args_set) + xterm_titles = "notitles" not in settings.features myroot = settings["ROOT"] root_config = trees[myroot]["root_config"] @@ -621,19 +674,6 @@ def action_depclean(settings, trees, ldpath_mtimes, if action == "depclean": emergelog(xterm_titles, " >>> depclean") - args_set = InternalPackageSet() - if myfiles: - args_set.update(myfiles) - matched_packages = False - for x in args_set: - if vardb.match(x): - matched_packages = True - break - if not matched_packages: - writemsg_level(">>> No packages selected for removal by %s\n" % \ - action) - return - writemsg_level("\nCalculating dependencies ") resolver_params = create_depgraph_params(myopts, "remove") resolver = depgraph(settings, trees, myopts, resolver_params, spinner) @@ -729,7 +769,7 @@ def action_depclean(settings, trees, ldpath_mtimes, resolver.display_problems() if not success: - return 1 + return 1, [], False, 0 def unresolved_deps(): @@ -771,7 +811,7 @@ def action_depclean(settings, trees, ldpath_mtimes, return False if unresolved_deps(): - return 1 + return 1, [], False, 0 graph = resolver.digraph.copy() required_pkgs_total = 0 @@ -1025,16 +1065,16 @@ def action_depclean(settings, trees, ldpath_mtimes, priority=UnmergeDepPriority(runtime=True), root=pkg.root)): resolver.display_problems() - return 1 + return 1, [], False, 0 writemsg_level("\nCalculating dependencies ") success = resolver._complete_graph() writemsg_level("\b\b... done!\n") resolver.display_problems() if not success: - return 1 + return 1, [], False, 0 if unresolved_deps(): - return 1 + return 1, [], False, 0 graph = resolver.digraph.copy() required_pkgs_total = 0 @@ -1043,7 +1083,7 @@ def action_depclean(settings, trees, ldpath_mtimes, required_pkgs_total += 1 cleanlist = create_cleanlist() if not cleanlist: - return 0 + return 0, [], False, required_pkgs_total clean_set = set(cleanlist) # Use a topological sort to create an unmerge order such that @@ -1135,25 +1175,8 @@ def action_depclean(settings, trees, ldpath_mtimes, graph.remove(node) cleanlist.append(node.cpv) - unmerge(root_config, myopts, "unmerge", cleanlist, - ldpath_mtimes, ordered=ordered) - - if action == "prune": - return - - if not cleanlist and "--quiet" in myopts: - return - - print "Packages installed: "+str(len(vardb.cpv_all())) - print "Packages in world: " + \ - str(len(root_config.sets["world"].getAtoms())) - print "Packages in system: " + \ - str(len(root_config.sets["system"].getAtoms())) - print "Required packages: "+str(required_pkgs_total) - if "--pretend" in myopts: - print "Number to remove: "+str(len(cleanlist)) - else: - print "Number removed: "+str(len(cleanlist)) + return 0, cleanlist, ordered, required_pkgs_total + return 0, [], False, required_pkgs_total def action_deselect(settings, trees, opts, atoms): root_config = trees[settings['ROOT']]['root_config'] -- cgit v1.2.3-1-g7c22