Index: tools/memory_inspector/memory_inspector/frontends/background_tasks.py |
diff --git a/tools/memory_inspector/memory_inspector/frontends/background_tasks.py b/tools/memory_inspector/memory_inspector/frontends/background_tasks.py |
index 61f3b40e8d7f39f7d2b2a76343dad825bbf2eda0..5b588ff6b43b4cc4d7ef64a197e986dbdf6df78c 100644 |
--- a/tools/memory_inspector/memory_inspector/frontends/background_tasks.py |
+++ b/tools/memory_inspector/memory_inspector/frontends/background_tasks.py |
@@ -11,14 +11,14 @@ operations, an instance of |BackgroundTask| is created here and the server |
returns just its id. The client can later poll the status of the asynchronous |
task to check for its progress. |
-From a technical viewpoint, each background task is just a python subprocess |
+From a technical viewpoint, each background task is just a python thread |
which communicates its progress updates through a Queue. The messages enqueued |
are tuples with the following format: (completion_ratio%, 'message string'). |
""" |
import datetime |
-import multiprocessing |
import Queue |
+import threading |
import time |
from memory_inspector.core import backends |
@@ -40,8 +40,8 @@ def StartTracer(process, storage_path, interval, count, trace_native_heap): |
count=count, |
trace_native_heap=trace_native_heap) |
task.start() |
- _tasks[task.pid] = task |
- return task.pid |
+ _tasks[task.ident] = task |
+ return task.ident |
def Get(task_id): |
@@ -49,9 +49,9 @@ def Get(task_id): |
def TerminateAll(): |
- for proc in _tasks.itervalues(): |
- if proc.is_alive(): |
- proc.terminate() |
+ for task in _tasks.itervalues(): |
+ if task.is_alive(): |
+ task.terminate() |
_tasks.clear() |
@@ -129,15 +129,23 @@ def TracerMain_(log, storage_path, backend_name, device_id, pid, interval, |
return 0 |
-class BackgroundTask(multiprocessing.Process): |
+class BackgroundTask(threading.Thread): |
def __init__(self, entry_point, *args, **kwargs): |
- self._log_queue = multiprocessing.Queue() |
+ self._log_queue = Queue.Queue() |
self._progress_log = [] # A list of tuples [(50%, 'msg1'), (100%, 'msg2')]. |
super(BackgroundTask, self).__init__( |
target=entry_point, |
args=((self._log_queue,) + args), # Just propagate all args. |
kwargs=kwargs) |
+ def run(self): |
+ try: |
+ super(BackgroundTask, self).run() |
+ except Exception, e: |
+ self._log_queue.put(( |
+ 100, 'An error occurred (%s). See the log for more details.' % e)) |
+ raise |
+ |
def GetProgress(self): |
""" Returns a tuple (completion_rate, message). """ |
while True: |
@@ -145,6 +153,4 @@ class BackgroundTask(multiprocessing.Process): |
self._progress_log += [self._log_queue.get(block=False)] |
except Queue.Empty: |
break |
- if not self.is_alive() and self.exitcode != 0: |
- return self._progress_log + [(100, 'Failed with code %d' % self.exitcode)] |
- return self._progress_log |
+ return self._progress_log |