[poppler] 2 commits - regtest/InterruptibleQueue.py regtest/TestReferences.py regtest/TestRun.py

Carlos Garcia Campos carlosgc at kemper.freedesktop.org
Fri Jan 1 04:13:03 PST 2016


 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 <carlosgc at gnome.org>
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 <carlosgc at gnome.org>
+#
+# 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 <adam.reichold at t-online.de>
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:


More information about the poppler mailing list