aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2011-01-15 16:00:35 -0800
committerZac Medico <zmedico@gentoo.org>2011-01-15 16:00:35 -0800
commitc4451a1e94212025e060cfd8e6a2341527202086 (patch)
tree5080bcc79734a5f93086dac12192ea0d621060eb /pym/_emerge/PollScheduler.py
parentWhen killed by signal, return 128 + signum. (diff)
downloadportage-c4451a1e94212025e060cfd8e6a2341527202086.tar.gz
portage-c4451a1e94212025e060cfd8e6a2341527202086.tar.bz2
portage-c4451a1e94212025e060cfd8e6a2341527202086.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.py31
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: