| 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
|
|
|