[meld] matchers.helpers: Handle terminating diffing subprocesses (bgo#790335)



commit c6a5b22b6501566620ab32a90016cd200eb1bb66
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sat Nov 18 07:20:36 2017 +1000

    matchers.helpers: Handle terminating diffing subprocesses (bgo#790335)
    
    These were previously a pool, and so we didn't have to bother with
    manually terminating the processes. However, we now maintain one per
    tab, just to get it out of the UI thread and on to a separate core.

 meld/filediff.py         |    3 +++
 meld/matchers/helpers.py |   13 +++++++++++++
 2 files changed, 16 insertions(+), 0 deletions(-)
---
diff --git a/meld/filediff.py b/meld/filediff.py
index 831f476..0756629 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -840,6 +840,9 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
         return response
 
     def on_delete_event(self):
+        # TODO: This should not be necessary; remove if and when we
+        # figure out what's keeping MeldDocs alive for too long.
+        del self._cached_match
         self.state = melddoc.STATE_CLOSING
         response = self.check_save_modified()
         if response == Gtk.ResponseType.OK:
diff --git a/meld/matchers/helpers.py b/meld/matchers/helpers.py
index 5710c9b..5f2e15c 100644
--- a/meld/matchers/helpers.py
+++ b/meld/matchers/helpers.py
@@ -14,6 +14,8 @@ log = logging.getLogger(__name__)
 
 class MatcherWorker(multiprocessing.Process):
 
+    END_TASK = -1
+
     matcher_class = myers.InlineMyersSequenceMatcher
 
     def __init__(self, tasks, results):
@@ -25,6 +27,9 @@ class MatcherWorker(multiprocessing.Process):
     def run(self):
         while True:
             task_id, (text1, textn) = self.tasks.get()
+            if task_id == self.END_TASK:
+                break
+
             try:
                 matcher = self.matcher_class(None, text1, textn)
                 self.results.put((task_id, matcher.get_opcodes()))
@@ -43,6 +48,8 @@ class CachedSequenceMatcher(object):
     eviction is overly simplistic, but is okay for our usage pattern.
     """
 
+    TASK_GRACE_PERIOD = 5
+
     def __init__(self, scheduler):
         """Create a new caching sequence matcher
 
@@ -62,6 +69,12 @@ class CachedSequenceMatcher(object):
         self.queued_matches = {}
         GLib.idle_add(self.thread.start)
 
+    def __del__(self):
+        self.tasks.put((MatcherWorker.END_TASK, ('', '')))
+        self.thread.join(self.TASK_GRACE_PERIOD)
+        if self.thread.exitcode is None:
+            self.thread.terminate()
+
     def match(self, text1, textn, cb):
         texts = (text1, textn)
         try:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]