TaskRunner starts the background thread only when needed

Test: libhidl_test
Test: hidl_test
Test: boots
Change-Id: I5b6de5cd4a475b0653102e8004953ba008288ab1
diff --git a/base/TaskRunner.cpp b/base/TaskRunner.cpp
index cd1df05..33117e7 100644
--- a/base/TaskRunner.cpp
+++ b/base/TaskRunner.cpp
@@ -22,7 +22,10 @@
 namespace details {
 
 TaskRunner::TaskRunner() {
-    mQueue = std::make_shared<SynchronizedQueue<Task>>();
+}
+
+void TaskRunner::start(size_t limit) {
+    mQueue = std::make_shared<SynchronizedQueue<Task>>(limit);
 
     // Allow the thread to continue running in background;
     // TaskRunner do not care about the std::thread object.
@@ -35,7 +38,9 @@
 }
 
 TaskRunner::~TaskRunner() {
-    mQueue->push(nullptr);
+    if (mQueue) {
+        mQueue->push(nullptr);
+    }
 }
 
 } // namespace details
diff --git a/base/include/hidl/SynchronizedQueue.h b/base/include/hidl/SynchronizedQueue.h
index 1813130..efb04e0 100644
--- a/base/include/hidl/SynchronizedQueue.h
+++ b/base/include/hidl/SynchronizedQueue.h
@@ -29,6 +29,7 @@
  */
 template <typename T>
 struct SynchronizedQueue {
+    SynchronizedQueue(size_t limit);
 
     /* Gets an item from the front of the queue.
      *
@@ -44,19 +45,18 @@
      */
     size_t size();
 
-    /* Sets the limit to the queue. Will fail
-     * the push operation if the limit is reached.
-     */
-    void setLimit(size_t limit);
-
 private:
     std::condition_variable mCondition;
     std::mutex mMutex;
     std::queue<T> mQueue;
-    size_t mQueueLimit = SIZE_MAX;
+    const size_t mQueueLimit;
 };
 
 template <typename T>
+SynchronizedQueue<T>::SynchronizedQueue(size_t limit) : mQueueLimit(limit) {
+}
+
+template <typename T>
 T SynchronizedQueue<T>::wait_pop() {
     std::unique_lock<std::mutex> lock(mMutex);
 
@@ -94,13 +94,6 @@
     return mQueue.size();
 }
 
-template <typename T>
-void SynchronizedQueue<T>::setLimit(size_t limit) {
-    std::unique_lock<std::mutex> lock(mMutex);
-
-    mQueueLimit = limit;
-}
-
 } // namespace details
 } // namespace hardware
 } // namespace android
diff --git a/base/include/hidl/TaskRunner.h b/base/include/hidl/TaskRunner.h
index b6e9a95..8ecceca 100644
--- a/base/include/hidl/TaskRunner.h
+++ b/base/include/hidl/TaskRunner.h
@@ -32,7 +32,7 @@
 public:
     using Task = std::function<void(void)>;
 
-    /* Kicks off the loop immediately. */
+    /* Create an empty task runner. Nothing will be done until start() is called. */
     TaskRunner();
 
     /*
@@ -43,19 +43,19 @@
     ~TaskRunner();
 
     /*
+     * Sets the queue limit. Fails the push operation once the limit is reached.
+     * Then kicks off the loop.
+     */
+    void start(size_t limit);
+
+    /*
      * Add a task. Return true if successful, false if
      * the queue's size exceeds limit or t doesn't contain a callable target.
      */
     inline bool push(const Task &t) {
-        return (!!t) && this->mQueue->push(t);
+        return (mQueue != nullptr) && (!!t) && this->mQueue->push(t);
     }
 
-    /*
-     * Sets the queue limit. Fails the push operation once the limit is reached.
-     */
-    inline void setLimit(size_t limit) {
-        this->mQueue->setLimit(limit);
-    }
 private:
     std::shared_ptr<SynchronizedQueue<Task>> mQueue;
 };