diff options
author | mukesh agrawal <quiche@google.com> | 2016-11-15 19:31:40 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-11-15 19:31:40 +0000 |
commit | 02b8923766241d9945f90c2a17b687c7670587ec (patch) | |
tree | 05757d3299dab1f296b9714202182c0549fe8cbc | |
parent | 9e228f1ec8f3b6764de1d72d826fb29aa6017e41 (diff) | |
parent | 8fbb6736ffd23e005396afb793c72cb048bbf7a6 (diff) | |
download | wifilogd-02b8923766241d9945f90c2a17b687c7670587ec.tar.gz |
MainLoop: improve error handling am: fd59221459
am: 8fbb6736ff
Change-Id: Ic53f2ae5da4a5e5aa8a659abd4f223c72398064a
-rw-r--r-- | main_loop.cpp | 20 | ||||
-rw-r--r-- | main_loop.h | 2 | ||||
-rw-r--r-- | tests/main_loop_unittest.cpp | 9 |
3 files changed, 28 insertions, 3 deletions
diff --git a/main_loop.cpp b/main_loop.cpp index 62bed31..8ad030a 100644 --- a/main_loop.cpp +++ b/main_loop.cpp @@ -30,6 +30,8 @@ namespace wifilogd { namespace { constexpr auto kMainBufferSizeBytes = 128 * 1024; +// TODO(b/32840641): Tune the sleep time. +constexpr auto kTransientErrorSleepTimeNsec = 100 * 1000; // 100 usec } MainLoop::MainLoop(const std::string& socket_name) @@ -53,8 +55,7 @@ void MainLoop::RunOnce() { std::tie(datagram_len, err) = os_->ReceiveDatagram(sock_fd_, input_buf.data(), input_buf.size()); if (err) { - // TODO(b/32098735): Increment stats counter. - // TODO(b/32481888): Improve error handling. + ProcessError(err); return; } @@ -67,5 +68,20 @@ void MainLoop::RunOnce() { Os::kInvalidFd); } +// Private methods below. + +void MainLoop::ProcessError(Os::Errno err) { + if (err == EINTR || err == ENOMEM) { + // TODO(b/32098735): Increment stats counter. + os_->Nanosleep(kTransientErrorSleepTimeNsec); + return; + } + + // Any other error is unexpected, and assumed to be non-recoverable. + // (If, e.g., our socket is in a bad state, then we won't be able to receive + // any new log messages.) + LOG(FATAL) << "Unexpected error: " << std::strerror(err); +} + } // namespace wifilogd } // namespace android diff --git a/main_loop.h b/main_loop.h index c5a4b48..53c42f8 100644 --- a/main_loop.h +++ b/main_loop.h @@ -39,6 +39,8 @@ class MainLoop { void RunOnce(); private: + void ProcessError(Os::Errno err); + std::unique_ptr<Os> os_; std::unique_ptr<CommandProcessor> command_processor_; // We use an int, rather than a unique_fd, because the file diff --git a/tests/main_loop_unittest.cpp b/tests/main_loop_unittest.cpp index db04027..b6c1141 100644 --- a/tests/main_loop_unittest.cpp +++ b/tests/main_loop_unittest.cpp @@ -109,9 +109,10 @@ TEST_F(MainLoopTest, RunOnceLimitsMaxSizeReportedToCommandProcessor) { main_loop_->RunOnce(); } -TEST_F(MainLoopTest, RunOnceDoesNotPassDataToCommandProcessorOnError) { +TEST_F(MainLoopTest, RunOnceSleepsAndDoesNotPassDataToCommandProcessorOnError) { EXPECT_CALL(*os_, ReceiveDatagram(_, _, protocol::kMaxMessageSize)) .WillOnce(Return(std::tuple<size_t, Os::Errno>{0, EINTR})); + EXPECT_CALL(*os_, Nanosleep(_)); EXPECT_CALL(*command_processor_, ProcessCommand(_, _, _)).Times(0); main_loop_->RunOnce(); } @@ -131,5 +132,11 @@ TEST_F(MainLoopDeathTest, CtorFailureToFetchControlSocketCausesDeath) { "Failed to get control socket"); } +TEST_F(MainLoopDeathTest, RunOnceTerminatesOnUnexpectedError) { + ON_CALL(*os_, ReceiveDatagram(_, _, protocol::kMaxMessageSize)) + .WillByDefault(Return(std::tuple<size_t, Os::Errno>{0, EFAULT})); + EXPECT_DEATH(main_loop_->RunOnce(), "Unexpected error"); +} + } // namespace wifilogd } // namespace android |