Snap for 9354090 from 9ae996d0a069cfd8e0517c74629f5bac54ed72c5 to tm-qpr2-release

Change-Id: Icab819399cd8f03933c5ede3c412c4c60d9f2f33
diff --git a/src/profiling/memory/unwinding.cc b/src/profiling/memory/unwinding.cc
index d500e0b..e52e8f0 100644
--- a/src/profiling/memory/unwinding.cc
+++ b/src/profiling/memory/unwinding.cc
@@ -198,6 +198,29 @@
   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 6b5bcdb..9bc41c3 100644
--- a/src/profiling/memory/unwinding.h
+++ b/src/profiling/memory/unwinding.h
@@ -85,6 +85,9 @@
       : 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 @@
   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_;
 };