diff options
author | Florian Mayer <fmayer@google.com> | 2018-05-18 10:43:14 +0100 |
---|---|---|
committer | Florian Mayer <fmayer@google.com> | 2018-05-18 14:12:53 +0100 |
commit | 870dd82f0a1190b1890ca3e592f68bc5bbece627 (patch) | |
tree | e8e7da00d1b12f7770f3ef727670af02e259a742 | |
parent | 361f1e2e39054b2002ce0b22b7c74387559610a8 (diff) | |
download | perfetto-870dd82f0a1190b1890ca3e592f68bc5bbece627.tar.gz |
Correctly handle EINTR.
This fixes a bug that made the CPU reader loop exit when the program
gets send SIGSTOP.
Cherry pick of http://aosp/689181.
Bug: 79969427
Merged-In: I09ae42adb5b211e0eae73364dcef1b4d33762ed8
Change-Id: I0f76ba9d3aba77a607175fc1f31ec7edcfa2afe6
-rw-r--r-- | src/ftrace_reader/cpu_reader.cc | 16 | ||||
-rw-r--r-- | src/ftrace_reader/cpu_reader.h | 5 |
2 files changed, 13 insertions, 8 deletions
diff --git a/src/ftrace_reader/cpu_reader.cc b/src/ftrace_reader/cpu_reader.cc index 39e0fb5a2..c9e86d233 100644 --- a/src/ftrace_reader/cpu_reader.cc +++ b/src/ftrace_reader/cpu_reader.cc @@ -145,7 +145,7 @@ CpuReader::CpuReader(const ProtoTranslationTable* table, worker_thread_ = std::thread(std::bind(&RunWorkerThread, cpu_, *trace_fd_, - *staging_write_fd_, on_data_available)); + *staging_write_fd_, on_data_available, &exiting_)); } CpuReader::~CpuReader() { @@ -155,17 +155,18 @@ CpuReader::~CpuReader() { // trace fd (which prevents another splice from starting), raise SIGPIPE and // wait for the worker to exit (i.e., to guarantee no splice is in progress) // and only then close the staging pipe. + exiting_ = true; trace_fd_.reset(); pthread_kill(worker_thread_.native_handle(), SIGPIPE); worker_thread_.join(); } // static -void CpuReader::RunWorkerThread( - size_t cpu, - int trace_fd, - int staging_write_fd, - const std::function<void()>& on_data_available) { +void CpuReader::RunWorkerThread(size_t cpu, + int trace_fd, + int staging_write_fd, + const std::function<void()>& on_data_available, + std::atomic<bool>* exiting) { #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) // This thread is responsible for moving data from the trace pipe into the @@ -188,11 +189,12 @@ void CpuReader::RunWorkerThread( // The kernel ftrace code has its own splice() implementation that can // occasionally fail with transient errors not reported in man 2 splice. // Just try again if we see these. - if (errno == ENOMEM || errno == EBUSY) { + if (errno == ENOMEM || errno == EBUSY || (errno == EINTR && !*exiting)) { PERFETTO_DPLOG("Transient splice failure -- retrying"); usleep(100 * 1000); continue; } + PERFETTO_DPLOG("Stopping CPUReader loop for CPU %zd.", cpu); PERFETTO_DCHECK(errno == EPIPE || errno == EINTR || errno == EBADF); break; // ~CpuReader is waiting to join this thread. } diff --git a/src/ftrace_reader/cpu_reader.h b/src/ftrace_reader/cpu_reader.h index ab2b3401e..7e6146339 100644 --- a/src/ftrace_reader/cpu_reader.h +++ b/src/ftrace_reader/cpu_reader.h @@ -21,6 +21,7 @@ #include <string.h> #include <array> +#include <atomic> #include <memory> #include <set> #include <thread> @@ -201,7 +202,8 @@ class CpuReader { static void RunWorkerThread(size_t cpu, int trace_fd, int staging_write_fd, - const std::function<void()>& on_data_available); + const std::function<void()>& on_data_available, + std::atomic<bool>* exiting); uint8_t* GetBuffer(); CpuReader(const CpuReader&) = delete; @@ -214,6 +216,7 @@ class CpuReader { base::ScopedFile staging_write_fd_; std::unique_ptr<uint8_t[]> buffer_; std::thread worker_thread_; + std::atomic<bool> exiting_{false}; PERFETTO_THREAD_CHECKER(thread_checker_) }; |