Simplify the implementation of TaskRunner.

TestRunner used to hold the std::thread pointer and
a pointer to a boolean flag. Simplify them:

* std::thread* is not needed because detach() allows
  the thread to run in background
* bool* is not needed; use a non-callable std::function
  to indicate end of queue.
* Use std::shared_ptr instead of raw pointer for mQueue
  to avoid weird pointer ownership management.

Test: libhidl_test
Test: hidl_test
Test: boots
Change-Id: I8fe7a6285bc537408ed559499951c17219e0df7f
diff --git a/base/TaskRunner.cpp b/base/TaskRunner.cpp
index 78add4c..cd1df05 100644
--- a/base/TaskRunner.cpp
+++ b/base/TaskRunner.cpp
@@ -22,26 +22,20 @@
 namespace details {
 
 TaskRunner::TaskRunner() {
-    bool *running = mRunning = new bool();
-    SynchronizedQueue<std::function<void(void)>> *q
-            = mQueue = new SynchronizedQueue<std::function<void(void)>>();
-    mThread = new std::thread([running, q] {
-        *running = true;
-        while (*running) {
-            (q->wait_pop())();
+    mQueue = std::make_shared<SynchronizedQueue<Task>>();
+
+    // Allow the thread to continue running in background;
+    // TaskRunner do not care about the std::thread object.
+    std::thread{[q = mQueue] {
+        Task nextTask;
+        while (!!(nextTask = q->wait_pop())) {
+            nextTask();
         }
-        delete q;
-        delete running;
-    });
+    }}.detach();
 }
+
 TaskRunner::~TaskRunner() {
-    bool *running = mRunning;
-    std::thread *t = mThread;
-    mThread->detach();
-    mQueue->push([running, t] {
-        *running = false;
-        delete t;
-    });
+    mQueue->push(nullptr);
 }
 
 } // namespace details
diff --git a/base/include/hidl/TaskRunner.h b/base/include/hidl/TaskRunner.h
index 7d340c7..b6e9a95 100644
--- a/base/include/hidl/TaskRunner.h
+++ b/base/include/hidl/TaskRunner.h
@@ -17,6 +17,7 @@
 #define ANDROID_HIDL_TASK_RUNNER_H
 
 #include "SynchronizedQueue.h"
+#include <memory>
 #include <thread>
 
 namespace android {
@@ -25,28 +26,28 @@
 
 /*
  * A background infinite loop that runs the Tasks push()'ed.
- * Just a simple single-threaded thread pool.
+ * Equivalent to a simple single-threaded Looper.
  */
 class TaskRunner {
 public:
+    using Task = std::function<void(void)>;
 
     /* Kicks off the loop immediately. */
     TaskRunner();
 
     /*
-     * Detaches the background thread and return immediately.
-     * Tasks in the queue will continue to be done sequentially, and _after_
-     * all tasks are done, the background thread releases the resources
-     * (the queue, the std::thread object, etc.)
+     * Notify the background thread to terminate and return immediately.
+     * Tasks in the queue will continue to be done sequentially in background
+     * until all tasks are finished.
      */
     ~TaskRunner();
 
     /*
      * Add a task. Return true if successful, false if
-     * the queue's size exceeds limit.
+     * the queue's size exceeds limit or t doesn't contain a callable target.
      */
-    inline bool push(const std::function<void(void)> &t) {
-        return this->mQueue->push(t);
+    inline bool push(const Task &t) {
+        return (!!t) && this->mQueue->push(t);
     }
 
     /*
@@ -56,11 +57,7 @@
         this->mQueue->setLimit(limit);
     }
 private:
-
-    // resources managed by the background thread.
-    bool *mRunning;
-    SynchronizedQueue<std::function<void(void)>> *mQueue;
-    std::thread *mThread;
+    std::shared_ptr<SynchronizedQueue<Task>> mQueue;
 };
 
 } // namespace details