| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/profiling/memlog_connection_manager.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/strings/stringprintf.h" |
| 10 #include "base/threading/thread.h" |
| 11 #include "chrome/profiling/allocation_tracker.h" |
| 12 #include "chrome/profiling/memlog_stream_parser.h" |
| 13 #include "chrome/profiling/profiling_globals.h" |
| 14 |
| 15 namespace profiling { |
| 16 |
| 17 struct MemlogConnectionManager::Connection { |
| 18 Connection(AllocationTracker::CompleteCallback complete_cb, |
| 19 int process_id, |
| 20 scoped_refptr<MemlogReceiverPipe> p) |
| 21 : thread(base::StringPrintf("Proc %d thread", process_id)), |
| 22 pipe(p), |
| 23 tracker(std::move(complete_cb)) {} |
| 24 |
| 25 ~Connection() {} |
| 26 |
| 27 base::Thread thread; |
| 28 |
| 29 scoped_refptr<MemlogReceiverPipe> pipe; |
| 30 scoped_refptr<MemlogStreamParser> parser; |
| 31 AllocationTracker tracker; |
| 32 }; |
| 33 |
| 34 MemlogConnectionManager::MemlogConnectionManager() {} |
| 35 |
| 36 MemlogConnectionManager::~MemlogConnectionManager() { |
| 37 // Clear the callback since the server is refcounted and may outlive us. |
| 38 server_->set_on_new_connection( |
| 39 base::RepeatingCallback<void(scoped_refptr<MemlogReceiverPipe>)>()); |
| 40 } |
| 41 |
| 42 void MemlogConnectionManager::StartConnections(const std::string& pipe_id) { |
| 43 server_ = new MemlogReceiverPipeServer( |
| 44 ProfilingGlobals::Get()->GetIORunner(), pipe_id, |
| 45 base::BindRepeating(&MemlogConnectionManager::OnNewConnection, |
| 46 base::Unretained(this))); |
| 47 server_->Start(); |
| 48 } |
| 49 |
| 50 void MemlogConnectionManager::OnNewConnection( |
| 51 scoped_refptr<MemlogReceiverPipe> new_pipe) { |
| 52 int remote_process = new_pipe->GetRemoteProcessID(); |
| 53 |
| 54 // Task to post to clean up the connection. Don't need to retain |this| since |
| 55 // it wil be called by objects owned by the MemlogConnectionManager. |
| 56 AllocationTracker::CompleteCallback complete_cb = base::BindOnce( |
| 57 &MemlogConnectionManager::OnConnectionCompleteThunk, |
| 58 base::Unretained(this), base::MessageLoop::current()->task_runner(), |
| 59 remote_process); |
| 60 |
| 61 std::unique_ptr<Connection> connection = base::MakeUnique<Connection>( |
| 62 std::move(complete_cb), remote_process, new_pipe); |
| 63 connection->thread.Start(); |
| 64 |
| 65 connection->parser = new MemlogStreamParser(&connection->tracker); |
| 66 new_pipe->SetReceiver(connection->thread.task_runner(), connection->parser); |
| 67 |
| 68 connections_[remote_process] = std::move(connection); |
| 69 } |
| 70 |
| 71 void MemlogConnectionManager::OnConnectionComplete(int process_id) { |
| 72 auto found = connections_.find(process_id); |
| 73 CHECK(found != connections_.end()); |
| 74 connections_.erase(found); |
| 75 |
| 76 // When all connections are closed, exit. |
| 77 if (connections_.empty()) |
| 78 ProfilingGlobals::Get()->QuitWhenIdle(); |
| 79 } |
| 80 |
| 81 // Posts back to the given thread the connection complete message. |
| 82 void MemlogConnectionManager::OnConnectionCompleteThunk( |
| 83 scoped_refptr<base::SingleThreadTaskRunner> main_loop, |
| 84 int process_id) { |
| 85 // This code is called by the allocation tracker which is owned by the |
| 86 // connection manager. When we tell the connection manager a connection is |
| 87 // done, we know the conncetion manager will still be in scope. |
| 88 main_loop->PostTask(FROM_HERE, |
| 89 base::Bind(&MemlogConnectionManager::OnConnectionComplete, |
| 90 base::Unretained(this), process_id)); |
| 91 } |
| 92 |
| 93 } // namespace profiling |
| OLD | NEW |