regtest/InterruptibleQueue.py | 68 ++++++++++++++++++++++++++++++++++++++++++ regtest/TestReferences.py | 6 +-- regtest/TestRun.py | 4 +- 3 files changed, 73 insertions(+), 5 deletions(-)
New commits: commit 25bb59a81de8a1b6dd23fec871a97ccb11fe9d64 Author: Carlos Garcia Campos <[email protected]> Date: Fri Jan 1 12:45:42 2016 +0100 regtest: Allow to interrupt run-tests and create-refs commands when multiple threads are used The Queue join implementation uses a non-timed wait that blocks the main thread, making it impossible to interrupt it with CTRL+C or sending SIGINT signal. Using any timeout value for wait would fix the problem, but Queue doesn't allow to pass a timeout to the join method. The Queue implementation is actually quite simple, so we can just add our own implementation with only the things we really need and use a timeout value when calling wait() in join(). diff --git a/regtest/InterruptibleQueue.py b/regtest/InterruptibleQueue.py new file mode 100644 index 0000000..4156e30 --- /dev/null +++ b/regtest/InterruptibleQueue.py @@ -0,0 +1,68 @@ +# InterruptibleQueue.py +# +# Copyright (C) 2016 Carlos Garcia Campos <[email protected]> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +from threading import Lock, Condition +from collections import deque +import sys + +class InterruptibleQueue: + """Simpler implementation of Queue that uses wait with a timeout to make join interruptile""" + + def __init__(self): + self._queue = deque() + self._mutex = Lock() + self._finished_condition = Condition(self._mutex) + self._not_empty_condition = Condition(self._mutex) + self._n_unfinished_tasks = 0 + + def task_done(self): + self._finished_condition.acquire() + try: + n_unfinished = self._n_unfinished_tasks - 1 + if n_unfinished == 0: + self._finished_condition.notify_all() + self._n_unfinished_tasks = n_unfinished + finally: + self._finished_condition.release() + + def join(self): + self._finished_condition.acquire() + try: + while self._n_unfinished_tasks: + self._finished_condition.wait(sys.float_info.max) + finally: + self._finished_condition.release() + + def put(self, item): + self._mutex.acquire() + try: + self._queue.append(item) + self._n_unfinished_tasks += 1 + self._not_empty_condition.notify() + finally: + self._mutex.release() + + def get(self): + self._not_empty_condition.acquire() + try: + while not len(self._queue): + self._not_empty_condition.wait() + return self._queue.popleft() + finally: + self._not_empty_condition.release() + diff --git a/regtest/TestReferences.py b/regtest/TestReferences.py index 1fb58b0..4eeb330 100644 --- a/regtest/TestReferences.py +++ b/regtest/TestReferences.py @@ -23,7 +23,7 @@ from Config import Config from Printer import get_printer from Utils import get_document_paths_from_dir, get_skipped_tests, get_passwords -from Queue import Queue +from InterruptibleQueue import InterruptibleQueue from threading import Thread, RLock class TestReferences: @@ -38,7 +38,7 @@ class TestReferences: self._total_tests = 1 self._n_tests = 0 - self._queue = Queue() + self._queue = InterruptibleQueue() self._lock = RLock() try: diff --git a/regtest/TestRun.py b/regtest/TestRun.py index fc3f6a7..95f28b4 100644 --- a/regtest/TestRun.py +++ b/regtest/TestRun.py @@ -24,7 +24,7 @@ import sys import os import errno -from Queue import Queue +from InterruptibleQueue import InterruptibleQueue from threading import Thread, RLock class TestRun: @@ -52,7 +52,7 @@ class TestRun: self._skipped = [] self._new = [] - self._queue = Queue() + self._queue = InterruptibleQueue() self._lock = RLock() try: commit ffb3ff633b124c476ab48bbcfce04d7f418df9bc Author: Adam Reichold <[email protected]> Date: Fri Jan 1 11:32:14 2016 +0100 regtest: Do not use the log printer with the TestReferences lock held diff --git a/regtest/TestReferences.py b/regtest/TestReferences.py index 05b08e2..1fb58b0 100644 --- a/regtest/TestReferences.py +++ b/regtest/TestReferences.py @@ -87,7 +87,7 @@ class TestReferences: backend.create_checksums(refs_path, self.config.checksums_only) with self._lock: self._n_tests += 1 - self.printer.printout_ln("[%d/%d] %s (%s): done" % (self._n_tests, self._total_tests, doc_path, backend.get_name())) + self.printer.printout_ln("[%d/%d] %s (%s): done" % (self._n_tests, self._total_tests, doc_path, backend.get_name())) def _worker_thread(self): while True: _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
