Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(317)

Unified Diff: tools/battor_agent/battor_agent_bin.cc

Issue 1949673003: [battor agent] Makes the main() thread also be the UI thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Synced to head Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/battor_agent/battor_agent_bin.cc
diff --git a/tools/battor_agent/battor_agent_bin.cc b/tools/battor_agent/battor_agent_bin.cc
index d309a12d80e9aa1a94705ece1146a681e4b7a4ab..a307e31a24e2799aa3b180f379c11aef0586d48f 100644
--- a/tools/battor_agent/battor_agent_bin.cc
+++ b/tools/battor_agent/battor_agent_bin.cc
@@ -42,8 +42,10 @@
#include "base/command_line.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/run_loop.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/thread_task_runner_handle.h"
#include "base/threading/thread.h"
#include "tools/battor_agent/battor_agent.h"
#include "tools/battor_agent/battor_error.h"
@@ -57,7 +59,6 @@ namespace {
const char kIoThreadName[] = "BattOr IO Thread";
const char kFileThreadName[] = "BattOr File Thread";
-const char kUiThreadName[] = "BattOr UI Thread";
const char kUsage[] =
"Start the battor_agent shell with:\n"
@@ -107,11 +108,7 @@ std::vector<std::string> TokenizeString(std::string cmd) {
// use a BattOrAgent to communicate with a BattOr.
class BattOrAgentBin : public BattOrAgent::Listener {
public:
- BattOrAgentBin()
- : done_(false, false),
- io_thread_(kIoThreadName),
- file_thread_(kFileThreadName),
- ui_thread_(kUiThreadName) {}
+ BattOrAgentBin() : io_thread_(kIoThreadName), file_thread_(kFileThreadName) {}
~BattOrAgentBin() { DCHECK(!agent_); }
@@ -127,44 +124,10 @@ class BattOrAgentBin : public BattOrAgent::Listener {
SetUp(path);
- std::string cmd;
- for (;;) {
- std::getline(std::cin, cmd);
-
- if (cmd == "StartTracing") {
- StartTracing();
- } else if (cmd.find("StopTracing") != std::string::npos) {
- std::vector<std::string> tokens = TokenizeString(cmd);
- if (tokens[0] != "StopTracing" || tokens.size() > 2) {
- std::cout << "Invalid StopTracing command." << endl;
- std::cout << kUsage << endl;
- continue;
- }
-
- // tokens[1] contains the optional output file argument, which allows
- // users to dump the trace to a file instead instead of to STDOUT.
- std::string trace_output_file =
- tokens.size() == 2 ? tokens[1] : std::string();
-
- StopTracing(trace_output_file);
- break;
- } else if (cmd == "SupportsExplicitClockSync") {
- PrintSupportsExplicitClockSync();
- } else if (cmd.find("RecordClockSyncMarker") != std::string::npos) {
- std::vector<std::string> tokens = TokenizeString(cmd);
- if (tokens.size() != 2 || tokens[0] != "RecordClockSyncMarker") {
- std::cout << "Invalid RecordClockSyncMarker command." << endl;
- std::cout << kUsage << endl;
- continue;
- }
-
- RecordClockSyncMarker(tokens[1]);
- } else if (cmd == "Exit") {
- break;
- } else {
- std::cout << kUsage << endl;
- }
- }
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&BattOrAgentBin::RunNextCommand, base::Unretained(this)));
+ ui_thread_run_loop_.Run();
TearDown();
return 0;
@@ -172,8 +135,6 @@ class BattOrAgentBin : public BattOrAgent::Listener {
// Performs any setup necessary for the BattOr binary to run.
void SetUp(const std::string& path) {
- // TODO(charliea): Investigate whether it's possible to replace this
- // separate thread with a combination of MessageLoopForIO and RunLoop.
base::Thread::Options io_thread_options;
io_thread_options.message_loop_type = base::MessageLoopForIO::TYPE_IO;
if (!io_thread_.StartWithOptions(io_thread_options)) {
@@ -182,23 +143,73 @@ class BattOrAgentBin : public BattOrAgent::Listener {
io_thread_.task_runner()->PostTask(
FROM_HERE,
- base::Bind(&BattOrAgentBin::CreateAgent, base::Unretained(this), path));
- done_.Wait();
+ base::Bind(&BattOrAgentBin::CreateAgent, base::Unretained(this), path,
+ base::ThreadTaskRunnerHandle::Get()));
}
// Performs any cleanup necessary after the BattOr binary is done running.
void TearDown() {
+ base::WaitableEvent done(false, false);
io_thread_.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&BattOrAgentBin::DeleteAgent,
+ base::Unretained(this), &done));
+ done.Wait();
+ }
+
+ void RunNextCommand() {
+ std::string cmd;
+ std::getline(std::cin, cmd);
+
+ if (cmd == "StartTracing") {
+ StartTracing();
+ } else if (cmd.find("StopTracing") != std::string::npos) {
+ std::vector<std::string> tokens = TokenizeString(cmd);
+
+ if (tokens[0] != "StopTracing" || tokens.size() > 2) {
+ std::cout << "Invalid StopTracing command." << endl;
+ std::cout << kUsage << endl;
+ PostRunNextCommand();
+ return;
+ }
+
+ // tokens[1] contains the optional output file argument, which allows
+ // users to dump the trace to a file instead instead of to STDOUT.
+ std::string trace_output_file =
+ tokens.size() == 2 ? tokens[1] : std::string();
+
+ StopTracing(trace_output_file);
+ } else if (cmd == "SupportsExplicitClockSync") {
+ PrintSupportsExplicitClockSync();
+ PostRunNextCommand();
+ } else if (cmd.find("RecordClockSyncMarker") != std::string::npos) {
+ std::vector<std::string> tokens = TokenizeString(cmd);
+ if (tokens.size() != 2 || tokens[0] != "RecordClockSyncMarker") {
+ std::cout << "Invalid RecordClockSyncMarker command." << endl;
+ std::cout << kUsage << endl;
+ PostRunNextCommand();
+ return;
+ }
+
+ RecordClockSyncMarker(tokens[1]);
+ } else if (cmd == "Exit") {
+ ui_thread_message_loop_.task_runner()->PostTask(
+ FROM_HERE, ui_thread_run_loop_.QuitClosure());
+ } else {
+ std::cout << kUsage << endl;
+ PostRunNextCommand();
+ }
+ }
+
+ void PostRunNextCommand() {
+ ui_thread_message_loop_.task_runner()->PostTask(
FROM_HERE,
- base::Bind(&BattOrAgentBin::DeleteAgent, base::Unretained(this)));
- done_.Wait();
+ base::Bind(&BattOrAgentBin::RunNextCommand, base::Unretained(this)));
}
void StartTracing() {
io_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&BattOrAgent::StartTracing, base::Unretained(agent_.get())));
- done_.Wait();
}
void OnStartTracingComplete(BattOrError error) override {
@@ -207,7 +218,7 @@ class BattOrAgentBin : public BattOrAgent::Listener {
else
HandleError(error);
- done_.Signal();
+ PostRunNextCommand();
}
void StopTracing(const std::string& trace_output_file) {
@@ -215,8 +226,6 @@ class BattOrAgentBin : public BattOrAgent::Listener {
io_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&BattOrAgent::StopTracing, base::Unretained(agent_.get())));
- done_.Wait();
- trace_output_file_ = std::string();
}
void OnStopTracingComplete(const std::string& trace,
@@ -238,14 +247,14 @@ class BattOrAgentBin : public BattOrAgent::Listener {
HandleError(error);
}
- done_.Signal();
+ ui_thread_message_loop_.task_runner()->PostTask(
+ FROM_HERE, ui_thread_run_loop_.QuitClosure());
}
void RecordClockSyncMarker(const std::string& marker) {
io_thread_.task_runner()->PostTask(
FROM_HERE, base::Bind(&BattOrAgent::RecordClockSyncMarker,
base::Unretained(agent_.get()), marker));
- done_.Wait();
}
void OnRecordClockSyncMarkerComplete(BattOrError error) override {
@@ -254,45 +263,41 @@ class BattOrAgentBin : public BattOrAgent::Listener {
else
HandleError(error);
- done_.Signal();
+ PostRunNextCommand();
}
// Postable task for creating the BattOrAgent. Because the BattOrAgent has
// uber thread safe dependencies, all interactions with it, including creating
// and deleting it, MUST happen on the IO thread.
- void CreateAgent(const std::string& path) {
- // In Chrome, we already have file and UI threads running. Because the
- // Chrome serial libraries rely on having those threads available, we have
- // to spin up our own because we're in a separate binary.
+ void CreateAgent(
+ const std::string& path,
+ scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) {
+ // In Chrome, we already have a file thread running. Because the Chrome
+ // serial library relies on having it available, we have to spin up our own.
if (!file_thread_.Start())
ExitFromThreadStartFailure(kFileThreadName);
- base::Thread::Options ui_thread_options;
- ui_thread_options.message_loop_type = base::MessageLoopForIO::TYPE_UI;
- if (!ui_thread_.StartWithOptions(ui_thread_options)) {
- ExitFromThreadStartFailure(kUiThreadName);
- }
-
agent_.reset(new BattOrAgent(path, this, file_thread_.task_runner(),
- ui_thread_.task_runner()));
- done_.Signal();
+ ui_thread_task_runner));
}
// Postable task for deleting the BattOrAgent. See the comment for
// CreateAgent() above regarding why this is necessary.
- void DeleteAgent() {
- agent_.reset(nullptr);
- done_.Signal();
+ void DeleteAgent(base::WaitableEvent* done) {
+ agent_.reset();
+ done->Signal();
}
private:
- // Event signaled when an async task has finished executing.
- base::WaitableEvent done_;
+ // NOTE: ui_thread_message_loop_ must appear before ui_thread_run_loop_ here
+ // because ui_thread_run_loop_ checks for the current MessageLoop during
+ // initialization.
+ base::MessageLoopForUI ui_thread_message_loop_;
+ base::RunLoop ui_thread_run_loop_;
// Threads needed for serial communication.
base::Thread io_thread_;
base::Thread file_thread_;
- base::Thread ui_thread_;
// The agent capable of asynchronously communicating with the BattOr.
std::unique_ptr<BattOrAgent> agent_;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698