From e3ab89057da44d73517d6e59841f75322d3f9f99 Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauld.mccarthy@gmail.com>
Date: Mon, 17 Apr 2017 20:49:47 +0100
Subject: [PATCH] Very subtle bugfix in TaskThread, which was causing
 ImageWrapper unit tests to lock up (as thousands of TaskThreads were being
 created, and not destroyed)

---
 fsl/utils/async.py | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/fsl/utils/async.py b/fsl/utils/async.py
index cd9f05e74..61e5aca90 100644
--- a/fsl/utils/async.py
+++ b/fsl/utils/async.py
@@ -691,6 +691,34 @@ class TaskThread(threading.Thread):
         while True:
 
             try:
+                # Clear ref to previous task if any. This
+                # is very important, because otherwise, if
+                # no tasks get posted to the queue, this
+                # loop will spin on queue.Empty exceptions,
+                # and the previous Task object will preserve
+                # a hanging ref to its function/method. Not
+                # ideal if the ref is to a method of the
+                # object which created this TaskThread, and
+                # needs to be GC'd!
+                task = None
+
+                # An example: Without clearing the task
+                # reference, the following code would
+                # result in the TaskThread spinning on empty
+                # forever, and would prevent the Blah
+                # instance from being GC'd:
+                #
+                #     class Blah(object):
+                #         def __init__(self):
+                #             tt = TaskThraed()
+                #             tt.enqueue(self.method)
+                #             tt.start()
+                #
+                #     def method(self):
+                #         pass
+                #
+                #     b = Blah()
+                #     del b
                 task = self.__q.get(timeout=1)
 
             except queue.Empty:
-- 
GitLab