summaryrefslogtreecommitdiffstats
path: root/pym
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2011-03-10 22:02:19 -0800
committerZac Medico <zmedico@gentoo.org>2011-03-14 09:24:01 -0700
commitd57e5baf22dccb5160249299e6db039f69a4214d (patch)
tree1ce1ff8ff947f33e3ebd085e4e51396a908b480f /pym
parentbcb3ead57e5f207652f506a13604f60dbebf047b (diff)
downloadportage-d57e5baf22dccb5160249299e6db039f69a4214d.tar.gz
portage-d57e5baf22dccb5160249299e6db039f69a4214d.tar.bz2
portage-d57e5baf22dccb5160249299e6db039f69a4214d.zip
PollScheduler: tweek termination logic
* PollScheduler and all subclasses now use the _terminated_tasks variable to check whether or not _terminate_tasks() has been called, and behave appropriately in that case. * The _schedule_tasks() method now has documentation about the relationship with _terminate_tasks() and _terminated_tasks.
Diffstat (limited to 'pym')
-rw-r--r--pym/_emerge/MetadataRegen.py15
-rw-r--r--pym/_emerge/PollScheduler.py21
-rw-r--r--pym/_emerge/QueueScheduler.py3
-rw-r--r--pym/_emerge/Scheduler.py8
4 files changed, 36 insertions, 11 deletions
diff --git a/pym/_emerge/MetadataRegen.py b/pym/_emerge/MetadataRegen.py
index 45c4f4d29..810317533 100644
--- a/pym/_emerge/MetadataRegen.py
+++ b/pym/_emerge/MetadataRegen.py
@@ -44,7 +44,7 @@ class MetadataRegen(PollScheduler):
portage.writemsg_stdout("Regenerating cache entries...\n")
every_cp.sort(reverse=True)
try:
- while not self._terminated.is_set():
+ while not self._terminated_tasks:
yield every_cp.pop()
except IndexError:
pass
@@ -56,13 +56,13 @@ class MetadataRegen(PollScheduler):
consumer = self._consumer
for cp in self._cp_iter:
- if self._terminated.is_set():
+ if self._terminated_tasks:
break
cp_set.add(cp)
portage.writemsg_stdout("Processing %s\n" % cp)
cpv_list = portdb.cp_list(cp)
for cpv in cpv_list:
- if self._terminated.is_set():
+ if self._terminated_tasks:
break
valid_pkgs.add(cpv)
ebuild_path, repo_path = portdb.findname2(cpv)
@@ -94,7 +94,7 @@ class MetadataRegen(PollScheduler):
while self._jobs:
self._poll_loop()
- if self._terminated.is_set():
+ if self._terminated_tasks:
self.returncode = 1
return
@@ -145,9 +145,10 @@ class MetadataRegen(PollScheduler):
@returns: True if there may be remaining tasks to schedule,
False otherwise.
"""
+ if self._terminated_tasks:
+ return False
+
while self._can_add_job():
- if self._terminated.is_set():
- return False
try:
metadata_process = next(self._process_iter)
except StopIteration:
@@ -167,7 +168,7 @@ class MetadataRegen(PollScheduler):
self.returncode = 1
self._error_count += 1
self._valid_pkgs.discard(metadata_process.cpv)
- if not self._terminated.is_set():
+ if not self._terminated_tasks:
portage.writemsg("Error processing %s, continuing...\n" % \
(metadata_process.cpv,), noiselevel=-1)
diff --git a/pym/_emerge/PollScheduler.py b/pym/_emerge/PollScheduler.py
index 94fd92407..8f4bd64b9 100644
--- a/pym/_emerge/PollScheduler.py
+++ b/pym/_emerge/PollScheduler.py
@@ -65,6 +65,24 @@ class PollScheduler(object):
"""
raise NotImplementedError()
+ def _schedule_tasks(self):
+ """
+ This is called from inside the _schedule() method, which
+ guarantees the following:
+
+ 1) It will not be called recursively.
+ 2) _terminate_tasks() will not be called while it is running.
+ 3) The state of the boolean _terminated_tasks variable will
+ not change while it is running.
+
+ Unless this method is used to perform user interface updates,
+ or something like that, the first thing it should do is check
+ the state of _terminated_tasks and if that is True then it
+ should return False immediately (since there's no need to
+ schedule anything after _terminate_tasks() has been called).
+ """
+ raise NotImplementedError()
+
def _schedule(self):
"""
Calls _schedule_tasks() and automatically returns early from
@@ -90,6 +108,9 @@ class PollScheduler(object):
return self._jobs
def _can_add_job(self):
+ if self._terminated_tasks:
+ return False
+
max_jobs = self._max_jobs
max_load = self._max_load
diff --git a/pym/_emerge/QueueScheduler.py b/pym/_emerge/QueueScheduler.py
index 8a7ea300a..2d727c95d 100644
--- a/pym/_emerge/QueueScheduler.py
+++ b/pym/_emerge/QueueScheduler.py
@@ -79,6 +79,9 @@ class QueueScheduler(PollScheduler):
@returns: True if there may be remaining tasks to schedule,
False otherwise.
"""
+ if self._terminated_tasks:
+ return False
+
while self._can_add_job():
n = self._max_jobs - self._running_job_count()
if n < 1:
diff --git a/pym/_emerge/Scheduler.py b/pym/_emerge/Scheduler.py
index 306c945d7..2f49c3420 100644
--- a/pym/_emerge/Scheduler.py
+++ b/pym/_emerge/Scheduler.py
@@ -1441,7 +1441,7 @@ class Scheduler(PollScheduler):
build_dir=build_dir, build_log=build_log,
pkg=pkg,
returncode=merge.returncode))
- if not self._terminated.is_set():
+ if not self._terminated_tasks:
self._failed_pkg_msg(self._failed_pkgs[-1], "install", "to")
self._status_display.failed = len(self._failed_pkgs)
return
@@ -1476,7 +1476,7 @@ class Scheduler(PollScheduler):
mtimedb.commit()
def _build_exit(self, build):
- if build.returncode == os.EX_OK and self._terminated.is_set():
+ if build.returncode == os.EX_OK and self._terminated_tasks:
# We've been interrupted, so we won't
# add this to the merge queue.
self.curval += 1
@@ -1505,7 +1505,7 @@ class Scheduler(PollScheduler):
build_dir=build_dir, build_log=build_log,
pkg=build.pkg,
returncode=build.returncode))
- if not self._terminated.is_set():
+ if not self._terminated_tasks:
self._failed_pkg_msg(self._failed_pkgs[-1], "emerge", "for")
self._status_display.failed = len(self._failed_pkgs)
self._deallocate_config(build.settings)
@@ -1685,7 +1685,7 @@ class Scheduler(PollScheduler):
self._poll_loop()
def _keep_scheduling(self):
- return bool(not self._terminated.is_set() and self._pkg_queue and \
+ return bool(not self._terminated_tasks and self._pkg_queue and \
not (self._failed_pkgs and not self._build_opts.fetchonly))
def _is_work_scheduled(self):