aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-12-01 00:12:32 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-12-01 00:12:32 +0000
commit936b5cedbc900e2064af6e18a3379c0a8eb21bb4 (patch)
treeb2ed97bfd142dac750e9b8d0835fefd744c8a2ee
parent91c299ecb7a222e22d51d90c9bfb047647ba7df3 (diff)
parent9ae996d0a069cfd8e0517c74629f5bac54ed72c5 (diff)
downloadperfetto-android13-qpr2-s11-release.tar.gz
Change-Id: Icab819399cd8f03933c5ede3c412c4c60d9f2f33
-rw-r--r--src/profiling/memory/unwinding.cc23
-rw-r--r--src/profiling/memory/unwinding.h21
2 files changed, 31 insertions, 13 deletions
diff --git a/src/profiling/memory/unwinding.cc b/src/profiling/memory/unwinding.cc
index d500e0b9c..e52e8f086 100644
--- a/src/profiling/memory/unwinding.cc
+++ b/src/profiling/memory/unwinding.cc
@@ -198,6 +198,29 @@ bool DoUnwind(WireMessage* msg, UnwindingMetadata* metadata, AllocRecord* out) {
return true;
}
+UnwindingWorker::~UnwindingWorker() {
+ if (thread_task_runner_.get() == nullptr) {
+ return;
+ }
+ std::mutex mutex;
+ std::condition_variable cv;
+
+ std::unique_lock<std::mutex> lock(mutex);
+ bool done = false;
+ thread_task_runner_.PostTask([&mutex, &cv, &done, this] {
+ for (auto& it : client_data_) {
+ auto& client_data = it.second;
+ client_data.sock->Shutdown(false);
+ }
+ client_data_.clear();
+
+ std::lock_guard<std::mutex> inner_lock(mutex);
+ done = true;
+ cv.notify_one();
+ });
+ cv.wait(lock, [&done] { return done; });
+}
+
void UnwindingWorker::OnDisconnect(base::UnixSocket* self) {
pid_t peer_pid = self->peer_pid_linux();
auto it = client_data_.find(peer_pid);
diff --git a/src/profiling/memory/unwinding.h b/src/profiling/memory/unwinding.h
index 6b5bcdbc1..9bc41c3b8 100644
--- a/src/profiling/memory/unwinding.h
+++ b/src/profiling/memory/unwinding.h
@@ -85,6 +85,9 @@ class UnwindingWorker : public base::UnixSocket::EventListener {
: delegate_(delegate),
thread_task_runner_(std::move(thread_task_runner)) {}
+ ~UnwindingWorker() override;
+ UnwindingWorker(UnwindingWorker&&) = default;
+
// Public API safe to call from other threads.
void PostDisconnectSocket(pid_t pid);
void PostHandoffSocket(HandoffData);
@@ -138,19 +141,11 @@ class UnwindingWorker : public base::UnixSocket::EventListener {
std::map<pid_t, ClientData> client_data_;
Delegate* delegate_;
- // Task runner with a dedicated thread. Keep last as instances this class are
- // currently (incorrectly) being destroyed on the main thread, instead of the
- // task thread. By destroying this task runner first, we ensure that the
- // UnwindingWorker is not active while the rest of its state is being
- // destroyed. Additionally this ensures that the destructing thread sees a
- // consistent view of the memory due to the ThreadTaskRunner's destructor
- // joining a thread.
- //
- // Additionally, keep the destructor defaulted, as its body would still race
- // against an active task thread.
- //
- // TODO(rsavitski): make the task thread own the object's lifetime (likely by
- // refactoring base::ThreadTaskRunner).
+ // Task runner with a dedicated thread. Keep last. By destroying this task
+ // runner first, we ensure that the UnwindingWorker is not active while the
+ // rest of its state is being destroyed. Additionally this ensures that the
+ // destructing thread sees a consistent view of the memory due to the
+ // ThreadTaskRunner's destructor joining a thread.
base::ThreadTaskRunner thread_task_runner_;
};