diff options
author | Zac Medico <zmedico@gentoo.org> | 2011-01-15 16:00:35 -0800 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2011-01-16 12:33:32 -0800 |
commit | 9cb900a38fed06178d8c6281c2e9466187666732 (patch) | |
tree | a653f727ba08ba16e74be5837bb2605505fe7251 /pym/_emerge/PollScheduler.py | |
parent | c8169e703374ab9efa4facd0a06994a85b6f87c2 (diff) | |
download | portage-9cb900a38fed06178d8c6281c2e9466187666732.tar.gz portage-9cb900a38fed06178d8c6281c2e9466187666732.tar.bz2 portage-9cb900a38fed06178d8c6281c2e9466187666732.zip |
Add PollScheduler.terminate() for interruption.
This allows PollScheduler instances to do basic cleanup and terminate
gracefully when SIGINT or SIGTERM signals are received.
Diffstat (limited to 'pym/_emerge/PollScheduler.py')
-rw-r--r-- | pym/_emerge/PollScheduler.py | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/pym/_emerge/PollScheduler.py b/pym/_emerge/PollScheduler.py index e71350e5b..a319066c0 100644 --- a/pym/_emerge/PollScheduler.py +++ b/pym/_emerge/PollScheduler.py @@ -1,4 +1,4 @@ -# Copyright 1999-2010 Gentoo Foundation +# Copyright 1999-2011 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import gzip @@ -6,6 +6,11 @@ import logging import select import time +try: + import threading +except ImportError: + import dummy_threading as threading + from portage import _encodings from portage import _unicode_encode from portage.util import writemsg_level @@ -21,6 +26,8 @@ class PollScheduler(object): __slots__ = ("output", "register", "schedule", "unregister") def __init__(self): + self._terminated = threading.Event() + self._terminated_tasks = False self._max_jobs = 1 self._max_load = None self._jobs = 0 @@ -38,6 +45,24 @@ class PollScheduler(object): schedule=self._schedule_wait, unregister=self._unregister) + def terminate(self): + """ + Schedules asynchronous, graceful termination of the scheduler + at the earliest opportunity. + + This method is thread-safe (and safe for signal handlers). + """ + self._terminated.set() + + def _terminate_tasks(self): + """ + Send signals to terminate all tasks. This is called once + from the event dispatching thread. All task should be + cleaned up at the earliest opportunity, but not necessarily + before this method returns. + """ + raise NotImplementedError() + def _schedule(self): """ Calls _schedule_tasks() and automatically returns early from @@ -120,6 +145,10 @@ class PollScheduler(object): raises StopIteration if timeout is None and there are no file descriptors to poll. """ + if self._terminated.is_set() and \ + not self._terminated_tasks: + self._terminated_tasks = True + self._terminate_tasks() if not self._poll_event_queue: self._poll(timeout) if not self._poll_event_queue: |