params: safe and efficient async writing parameters (#25912)

* Safe and efficient asynchronous writing parameters

* call putNonBlocking in locationd

* remove space

* ->AsyncWriter

* remove semicolon

* use member function

* asyc write multiple times

* add test case for AsyncWriter

* merge master

* add missing include

* public

* cleanup

* create once

* cleanup

* update that

* explicit waiting

* improve test case

---------

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
old-commit-hash: 0d797f4e8b2552192669d0329c14849f0a970066
This commit is contained in:
Dean Lee
2023-09-06 23:50:28 +08:00
committed by GitHub
parent 6394bf09d3
commit 08e70aecb2
14 changed files with 123 additions and 39 deletions
+31
View File
@@ -7,6 +7,7 @@
#include <csignal>
#include <unordered_map>
#include "common/queue.h"
#include "common/swaglog.h"
#include "common/util.h"
#include "system/hardware/hw.h"
@@ -327,3 +328,33 @@ void Params::clearAll(ParamKeyType key_type) {
fsync_dir(getParamPath());
}
void Params::putNonBlocking(const std::string &key, const std::string &val) {
static AsyncWriter async_writer;
async_writer.queue({params_path, key, val});
}
// AsyncWriter
AsyncWriter::~AsyncWriter() {
if (future.valid()) {
future.wait();
}
}
void AsyncWriter::queue(const std::tuple<std::string, std::string, std::string> &dat) {
q.push(dat);
// start thread on demand
if (!future.valid() || future.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready) {
future = std::async(std::launch::async, &AsyncWriter::write, this);
}
}
void AsyncWriter::write() {
std::tuple<std::string, std::string, std::string> dat;
while (q.try_pop(dat, 0)) {
auto &[path, key, value] = dat;
Params(path).put(key, value);
}
}