Create thread in passthrough objects lazily.
Also, moved SynchronizedQueue to not be exported
becaue it's not used outside of the library.
Notice, it would be cleaner to add variables to TaskRunner
and then use those to determine if it's initialized or not.
However, the ABI of TaskRunner is tied up in HIDL clients.
Perhaps in the future, we can consider renaming
SynchronizedQueue to be called TaskRunnerImpl.
Bug: 38039413
Test: boot + hidl_test
Change-Id: Id5dbffe0196447c7798ba89df0ff8c69b6796210
diff --git a/base/TaskRunner.cpp b/base/TaskRunner.cpp
index 782b40b..d4357bf 100644
--- a/base/TaskRunner.cpp
+++ b/base/TaskRunner.cpp
@@ -15,6 +15,9 @@
*/
#include <hidl/TaskRunner.h>
+
+#include "SynchronizedQueue.h"
+
#include <thread>
namespace android {
@@ -26,15 +29,6 @@
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.
- std::thread{[q = mQueue] {
- Task nextTask;
- while (!!(nextTask = q->wait_pop())) {
- nextTask();
- }
- }}.detach();
}
TaskRunner::~TaskRunner() {
@@ -44,7 +38,28 @@
}
bool TaskRunner::push(const Task &t) {
- return (mQueue != nullptr) && (!!t) && this->mQueue->push(t);
+ if (mQueue == nullptr || !t) {
+ return false;
+ }
+
+ {
+ std::unique_lock<std::mutex> lock = mQueue->lock();
+
+ if (!mQueue->isInitializedLocked()) {
+ // 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();
+ }
+ }}.detach();
+
+ mQueue->setInitializedLocked(true);
+ }
+ }
+
+ return this->mQueue->push(t);
}
} // namespace details