From c2f1f722a6fffc0e016bc7bbdfdc17271e814971 Mon Sep 17 00:00:00 2001 From: Janis Danisevskis Date: Fri, 16 Aug 2019 14:54:55 -0700 Subject: [PATCH] Keymaster worker threads stick around for 30s This patch makes keymaster worker threads linger for 30s in anticipation of more incomming requests. Change-Id: I76069c74d7f013482a777dfcf279d55aeb8e1c00 --- keystore/keymaster_worker.cpp | 33 ++++++++++++++++++++++++--------- keystore/keymaster_worker.h | 1 + 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/keystore/keymaster_worker.cpp b/keystore/keymaster_worker.cpp index f6d56211..911815e0 100644 --- a/keystore/keymaster_worker.cpp +++ b/keystore/keymaster_worker.cpp @@ -32,8 +32,12 @@ #include "key_proto_handler.h" #include "keystore_utils.h" +#include + namespace keystore { +using namespace std::chrono; + constexpr size_t kMaxOperations = 15; using AndroidKeymasterArguments = android::security::keymaster::KeymasterArguments; @@ -44,23 +48,34 @@ using android::security::keymaster::OperationResult; Worker::Worker() {} Worker::~Worker() { std::unique_lock lock(pending_requests_mutex_); - pending_requests_cond_var_.wait(lock, [this] { return pending_requests_.empty(); }); + terminate_ = true; + pending_requests_cond_var_.notify_all(); + pending_requests_cond_var_.wait(lock, [this] { return !running_; }); } void Worker::addRequest(WorkerTask request) { std::unique_lock lock(pending_requests_mutex_); - bool start_thread = pending_requests_.empty(); + bool start_thread = !running_; + running_ = true; pending_requests_.push(std::move(request)); lock.unlock(); + pending_requests_cond_var_.notify_all(); if (start_thread) { auto worker = std::thread([this] { std::unique_lock lock(pending_requests_mutex_); - running_ = true; - while (!pending_requests_.empty()) { - auto request = std::move(pending_requests_.front()); - lock.unlock(); - request(); - lock.lock(); - pending_requests_.pop(); + while (running_) { + // Wait for 30s if the request queue is empty, then kill die. + // Die immediately if termiate_ was set which happens in the destructor. + auto status = pending_requests_cond_var_.wait_for( + lock, 30s, [this]() { return !pending_requests_.empty() || terminate_; }); + if (status && !terminate_) { + auto request = std::move(pending_requests_.front()); + lock.unlock(); + request(); + lock.lock(); + pending_requests_.pop(); + } else { + running_ = false; + } pending_requests_cond_var_.notify_all(); } }); diff --git a/keystore/keymaster_worker.h b/keystore/keymaster_worker.h index 2c72c801..31657636 100644 --- a/keystore/keymaster_worker.h +++ b/keystore/keymaster_worker.h @@ -115,6 +115,7 @@ class Worker { std::mutex pending_requests_mutex_; std::condition_variable pending_requests_cond_var_; bool running_ = false; + bool terminate_ = false; public: Worker();