diff options
-rw-r--r-- | apex/apex_manifest.json | 2 | ||||
-rw-r--r-- | statsd/src/main.cpp | 44 |
2 files changed, 28 insertions, 18 deletions
diff --git a/apex/apex_manifest.json b/apex/apex_manifest.json index 0fb32272..af99f74f 100644 --- a/apex/apex_manifest.json +++ b/apex/apex_manifest.json @@ -1,5 +1,5 @@ { "name": "com.android.os.statsd", - "version": 339990000 + "version": 330400000 } diff --git a/statsd/src/main.cpp b/statsd/src/main.cpp index bd2c0e42..67bb65db 100644 --- a/statsd/src/main.cpp +++ b/statsd/src/main.cpp @@ -39,20 +39,12 @@ using std::make_shared; shared_ptr<StatsService> gStatsService = nullptr; sp<StatsSocketListener> gSocketListener = nullptr; +int gCtrlPipe[2]; void signalHandler(int sig) { - if (sig == SIGPIPE) { - // ShellSubscriber uses SIGPIPE as a signal to detect the end of the - // client process. Don't prematurely exit(1) here. Instead, ignore the - // signal and allow the write call to return EPIPE. - ALOGI("statsd received SIGPIPE. Ignoring signal."); - return; - } - - if (gSocketListener != nullptr) gSocketListener->stopListener(); - if (gStatsService != nullptr) gStatsService->Terminate(); ALOGW("statsd terminated on receiving signal %d.", sig); - exit(1); + const char c = 'q'; + write(gCtrlPipe[1], &c, 1); } void registerSignalHandlers() @@ -60,11 +52,15 @@ void registerSignalHandlers() struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; - sa.sa_handler = signalHandler; + + sa.sa_handler = SIG_IGN; + // ShellSubscriber uses SIGPIPE as a signal to detect the end of the + // client process. Don't prematurely exit(1) here. Instead, ignore the + // signal and allow the write call to return EPIPE. sigaction(SIGPIPE, &sa, nullptr); - sigaction(SIGHUP, &sa, nullptr); - sigaction(SIGINT, &sa, nullptr); - sigaction(SIGQUIT, &sa, nullptr); + + pipe2(gCtrlPipe, O_CLOEXEC); + sa.sa_handler = signalHandler; sigaction(SIGTERM, &sa, nullptr); } @@ -92,8 +88,6 @@ int main(int /*argc*/, char** /*argv*/) { return -1; } - registerSignalHandlers(); - gStatsService->sayHiToStatsCompanion(); gStatsService->Startup(); @@ -106,6 +100,22 @@ int main(int /*argc*/, char** /*argv*/) { exit(1); } + // Use self-pipe to notify this thread to gracefully quit + // when receiving SIGTERM + registerSignalHandlers(); + std::thread([] { + while (true) { + char c; + int i = read(gCtrlPipe[0], &c, 1); + if (i < 0) { + if (errno == EINTR) continue; + } + gSocketListener->stopListener(); + gStatsService->Terminate(); + exit(1); + } + }).detach(); + // Loop forever -- the reports run on this thread in a handler, and the // binder calls remain responsive in their pool of one thread. while (true) { |