Chromium Code Reviews| 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_receiver_pipe_server_win.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/memory/ptr_util.h" | |
| 9 #include "base/message_loop/message_loop.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | |
| 11 #include "chrome/common/profiling/memlog_stream.h" | |
| 12 | |
| 13 namespace profiling { | |
| 14 | |
| 15 namespace { | |
| 16 | |
| 17 // Use a large buffer for our pipe. We don't want the sender to block | |
| 18 // if at all possible since it will slow the app down quite a bit. Windows | |
| 19 // seems to max out a 64K per read so we use that (larger would be better if it | |
| 20 // worked). | |
|
awong
2017/06/15 21:32:47
Cite source for this information?
brettw
2017/06/15 22:12:22
Done.
| |
| 21 const int kReadBufferSize = 1024 * 64; | |
| 22 | |
| 23 } // namespace | |
| 24 | |
| 25 MemlogReceiverPipeServer::MemlogReceiverPipeServer( | |
| 26 base::TaskRunner* io_runner, | |
| 27 const std::string& pipe_id, | |
| 28 NewConnectionCallback on_new_conn) | |
| 29 : io_runner_(io_runner), | |
| 30 pipe_id_(base::ASCIIToUTF16(pipe_id)), | |
| 31 on_new_connection_(on_new_conn) {} | |
| 32 | |
| 33 MemlogReceiverPipeServer::~MemlogReceiverPipeServer() { | |
| 34 // TODO(brettw) we should ensure this destructor is not called when there are | |
| 35 // pending I/O operations as per RegisterIOHandler documentation. | |
| 36 } | |
| 37 | |
| 38 void MemlogReceiverPipeServer::Start() { | |
| 39 // It's important that the first call to CreatePipeInstance be here (which | |
| 40 // is called on the main thread) instead of on the background thread. | |
| 41 // Otherwise, the creation of the first pipe instance on the background | |
| 42 // thread and the launching of the child process will race. But the child | |
| 43 // process expects the pipe to already have been created. | |
|
awong
2017/06/15 21:32:47
This is a great comment...but I don't see how this
brettw
2017/06/15 22:12:22
Thanks for noticing, the comment is wrong. It expl
| |
| 44 io_runner_->PostTask( | |
| 45 FROM_HERE, | |
| 46 base::Bind(&MemlogReceiverPipeServer::ScheduleNewConnection, this, true)); | |
| 47 } | |
| 48 | |
| 49 base::string16 MemlogReceiverPipeServer::GetPipeName() const { | |
| 50 base::string16 pipe_name(kWindowsPipePrefix); | |
| 51 pipe_name.append(pipe_id_); | |
| 52 return pipe_name; | |
| 53 } | |
| 54 | |
| 55 HANDLE MemlogReceiverPipeServer::CreatePipeInstance(bool first_instance) const { | |
| 56 base::string16 pipe_name = GetPipeName(); | |
| 57 | |
| 58 DWORD open_mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED; | |
| 59 if (first_instance) | |
| 60 open_mode |= FILE_FLAG_FIRST_PIPE_INSTANCE; | |
| 61 | |
| 62 return ::CreateNamedPipe( | |
| 63 pipe_name.c_str(), open_mode, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, | |
| 64 PIPE_UNLIMITED_INSTANCES, kReadBufferSize, kReadBufferSize, 5000, NULL); | |
|
awong
2017/06/15 21:32:47
kBufferSize seems more appropriate if you're using
brettw
2017/06/15 22:12:21
Done.
| |
| 65 } | |
| 66 | |
| 67 void MemlogReceiverPipeServer::ScheduleNewConnection(bool first_instance) { | |
| 68 DCHECK(!current_); | |
| 69 // Need Unretained to avoid creating a reference cycle. | |
| 70 current_ = base::MakeUnique<MemlogReceiverPipe::CompletionThunk>( | |
| 71 CreatePipeInstance(first_instance), | |
| 72 base::BindRepeating(&MemlogReceiverPipeServer::OnIOCompleted, | |
| 73 base::Unretained(this))); | |
| 74 ::ConnectNamedPipe(current_->handle(), current_->overlapped()); | |
| 75 } | |
| 76 | |
| 77 void MemlogReceiverPipeServer::OnIOCompleted(size_t bytes_transfered, | |
| 78 DWORD error) { | |
| 79 scoped_refptr<MemlogReceiverPipe> pipe( | |
| 80 new MemlogReceiverPipe(std::move(current_))); | |
| 81 ScheduleNewConnection(false); | |
| 82 | |
| 83 if (!on_new_connection_.is_null()) | |
| 84 on_new_connection_.Run(pipe); | |
| 85 pipe->StartReadingOnIOThread(); | |
| 86 } | |
| 87 | |
| 88 } // namespace profiling | |
| OLD | NEW |