[tracing] Add IOHandler::OnIOCompleted trace event
Without this event, BrowserThread::IO can appear idle in traces while it's actually processing native events. IOCompletion being Windows-only, other platforms will need to be implemented separately in their own way once this has proven useful. Example trace with this CL : https://snipboard.io/93MeYg.jpg (green toplevel bars are the new event) Also took advantage of this to drive-by cleanup some old style construction paradigms in old code. R=fdoray@chromium.org Bug: 899897 Change-Id: I0688556413687896b880c172a00d2c4eb8c1b07e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2134772 Reviewed-by: Ken Rockot <rockot@google.com> Reviewed-by: Gary Kacmarcik <garykac@chromium.org> Reviewed-by: Maksim Orlovich <morlovich@chromium.org> Reviewed-by: François Doray <fdoray@chromium.org> Auto-Submit: Gabriel Charette <gab@chromium.org> Commit-Queue: Gabriel Charette <gab@chromium.org> Cr-Commit-Position: refs/heads/master@{#757988}
This commit is contained in:

committed by
Commit Bot

parent
d0dd50886b
commit
96d5c648d4
base/message_loop
mojo/core
net
base
disk_cache
blockfile
remoting/host/win
services/device/serial
@ -387,7 +387,7 @@ class TestIOHandler : public MessagePumpForIO::IOHandler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TestIOHandler::TestIOHandler(const wchar_t* name, HANDLE signal, bool wait)
|
TestIOHandler::TestIOHandler(const wchar_t* name, HANDLE signal, bool wait)
|
||||||
: signal_(signal), wait_(wait) {
|
: MessagePumpForIO::IOHandler(FROM_HERE), signal_(signal), wait_(wait) {
|
||||||
memset(buffer_, 0, sizeof(buffer_));
|
memset(buffer_, 0, sizeof(buffer_));
|
||||||
|
|
||||||
file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
|
file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
|
||||||
|
@ -544,6 +544,11 @@ MessagePumpForIO::IOContext::IOContext() {
|
|||||||
memset(&overlapped, 0, sizeof(overlapped));
|
memset(&overlapped, 0, sizeof(overlapped));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessagePumpForIO::IOHandler::IOHandler(const Location& from_here)
|
||||||
|
: io_handler_location_(from_here) {}
|
||||||
|
|
||||||
|
MessagePumpForIO::IOHandler::~IOHandler() = default;
|
||||||
|
|
||||||
MessagePumpForIO::MessagePumpForIO() {
|
MessagePumpForIO::MessagePumpForIO() {
|
||||||
port_.Set(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr,
|
port_.Set(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr,
|
||||||
reinterpret_cast<ULONG_PTR>(nullptr), 1));
|
reinterpret_cast<ULONG_PTR>(nullptr), 1));
|
||||||
@ -678,6 +683,9 @@ bool MessagePumpForIO::WaitForIOCompletion(DWORD timeout, IOHandler* filter) {
|
|||||||
// Save this item for later
|
// Save this item for later
|
||||||
completed_io_.push_back(item);
|
completed_io_.push_back(item);
|
||||||
} else {
|
} else {
|
||||||
|
TRACE_EVENT2("base,toplevel", "IOHandler::OnIOCompleted", "dest_file",
|
||||||
|
item.handler->io_handler_location().file_name(), "dest_func",
|
||||||
|
item.handler->io_handler_location().function_name());
|
||||||
item.handler->OnIOCompleted(item.context, item.bytes_transfered,
|
item.handler->OnIOCompleted(item.context, item.bytes_transfered,
|
||||||
item.error);
|
item.error);
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "base/base_export.h"
|
#include "base/base_export.h"
|
||||||
|
#include "base/location.h"
|
||||||
#include "base/message_loop/message_pump.h"
|
#include "base/message_loop/message_pump.h"
|
||||||
#include "base/observer_list.h"
|
#include "base/observer_list.h"
|
||||||
#include "base/optional.h"
|
#include "base/optional.h"
|
||||||
@ -198,7 +199,7 @@ class BASE_EXPORT MessagePumpForIO : public MessagePumpWin {
|
|||||||
//
|
//
|
||||||
// Typical use #1:
|
// Typical use #1:
|
||||||
// class MyFile : public IOHandler {
|
// class MyFile : public IOHandler {
|
||||||
// MyFile() {
|
// MyFile() : IOHandler(FROM_HERE) {
|
||||||
// ...
|
// ...
|
||||||
// message_pump->RegisterIOHandler(file_, this);
|
// message_pump->RegisterIOHandler(file_, this);
|
||||||
// }
|
// }
|
||||||
@ -228,9 +229,14 @@ class BASE_EXPORT MessagePumpForIO : public MessagePumpWin {
|
|||||||
// message_pump->WaitForIOCompletion(INFINITE, this);
|
// message_pump->WaitForIOCompletion(INFINITE, this);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
class IOHandler {
|
class BASE_EXPORT IOHandler {
|
||||||
public:
|
public:
|
||||||
virtual ~IOHandler() {}
|
explicit IOHandler(const Location& from_here);
|
||||||
|
virtual ~IOHandler();
|
||||||
|
|
||||||
|
IOHandler(const IOHandler&) = delete;
|
||||||
|
IOHandler& operator=(const IOHandler&) = delete;
|
||||||
|
|
||||||
// This will be called once the pending IO operation associated with
|
// This will be called once the pending IO operation associated with
|
||||||
// |context| completes. |error| is the Win32 error code of the IO operation
|
// |context| completes. |error| is the Win32 error code of the IO operation
|
||||||
// (ERROR_SUCCESS if there was no error). |bytes_transfered| will be zero
|
// (ERROR_SUCCESS if there was no error). |bytes_transfered| will be zero
|
||||||
@ -238,6 +244,11 @@ class BASE_EXPORT MessagePumpForIO : public MessagePumpWin {
|
|||||||
virtual void OnIOCompleted(IOContext* context,
|
virtual void OnIOCompleted(IOContext* context,
|
||||||
DWORD bytes_transfered,
|
DWORD bytes_transfered,
|
||||||
DWORD error) = 0;
|
DWORD error) = 0;
|
||||||
|
|
||||||
|
const Location& io_handler_location() { return io_handler_location_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Location io_handler_location_;
|
||||||
};
|
};
|
||||||
|
|
||||||
MessagePumpForIO();
|
MessagePumpForIO();
|
||||||
|
@ -85,6 +85,7 @@ class ChannelWin : public Channel,
|
|||||||
HandlePolicy handle_policy,
|
HandlePolicy handle_policy,
|
||||||
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
|
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
|
||||||
: Channel(delegate, handle_policy),
|
: Channel(delegate, handle_policy),
|
||||||
|
base::MessagePumpForIO::IOHandler(FROM_HERE),
|
||||||
self_(this),
|
self_(this),
|
||||||
io_task_runner_(io_task_runner) {
|
io_task_runner_(io_task_runner) {
|
||||||
if (connection_params.server_endpoint().is_valid()) {
|
if (connection_params.server_endpoint().is_valid()) {
|
||||||
|
@ -62,8 +62,8 @@ class FileStream::Context {
|
|||||||
// file_stream_context_{win,posix}.cc.
|
// file_stream_context_{win,posix}.cc.
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
explicit Context(const scoped_refptr<base::TaskRunner>& task_runner);
|
explicit Context(scoped_refptr<base::TaskRunner> task_runner);
|
||||||
Context(base::File file, const scoped_refptr<base::TaskRunner>& task_runner);
|
Context(base::File file, scoped_refptr<base::TaskRunner> task_runner);
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
~Context() override;
|
~Context() override;
|
||||||
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
|
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
|
||||||
@ -172,7 +172,7 @@ class FileStream::Context {
|
|||||||
// Deletes an orphaned context.
|
// Deletes an orphaned context.
|
||||||
void DeleteOrphanedContext();
|
void DeleteOrphanedContext();
|
||||||
|
|
||||||
// The ReadFile call on Windows can execute synchonously at times.
|
// The ReadFile call on Windows can execute synchronously at times.
|
||||||
// http://support.microsoft.com/kb/156932. This ends up blocking the calling
|
// http://support.microsoft.com/kb/156932. This ends up blocking the calling
|
||||||
// thread which is undesirable. To avoid this we execute the ReadFile call
|
// thread which is undesirable. To avoid this we execute the ReadFile call
|
||||||
// on a worker thread.
|
// on a worker thread.
|
||||||
@ -217,10 +217,10 @@ class FileStream::Context {
|
|||||||
#endif // defined(OS_WIN)
|
#endif // defined(OS_WIN)
|
||||||
|
|
||||||
base::File file_;
|
base::File file_;
|
||||||
bool async_in_progress_;
|
bool async_in_progress_ = false;
|
||||||
|
|
||||||
bool orphaned_;
|
bool orphaned_ = false;
|
||||||
scoped_refptr<base::TaskRunner> task_runner_;
|
const scoped_refptr<base::TaskRunner> task_runner_;
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
base::MessagePumpForIO::IOContext io_context_;
|
base::MessagePumpForIO::IOContext io_context_;
|
||||||
@ -228,16 +228,16 @@ class FileStream::Context {
|
|||||||
scoped_refptr<IOBuffer> in_flight_buf_;
|
scoped_refptr<IOBuffer> in_flight_buf_;
|
||||||
// This flag is set to true when we receive a Read request which is queued to
|
// This flag is set to true when we receive a Read request which is queued to
|
||||||
// the thread pool.
|
// the thread pool.
|
||||||
bool async_read_initiated_;
|
bool async_read_initiated_ = false;
|
||||||
// This flag is set to true when we receive a notification ReadAsyncResult()
|
// This flag is set to true when we receive a notification ReadAsyncResult()
|
||||||
// on the calling thread which indicates that the asynchronous Read
|
// on the calling thread which indicates that the asynchronous Read
|
||||||
// operation is complete.
|
// operation is complete.
|
||||||
bool async_read_completed_;
|
bool async_read_completed_ = false;
|
||||||
// This flag is set to true when we receive an IO completion notification for
|
// This flag is set to true when we receive an IO completion notification for
|
||||||
// an asynchonously initiated Read operaton. OnIOComplete().
|
// an asynchronously initiated Read operation. OnIOComplete().
|
||||||
bool io_complete_for_read_received_;
|
bool io_complete_for_read_received_ = false;
|
||||||
// Tracks the result of the IO completion operation. Set in OnIOComplete.
|
// Tracks the result of the IO completion operation. Set in OnIOComplete.
|
||||||
int result_;
|
int result_ = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Context);
|
DISALLOW_COPY_AND_ASSIGN(Context);
|
||||||
|
@ -21,18 +21,12 @@
|
|||||||
|
|
||||||
namespace net {
|
namespace net {
|
||||||
|
|
||||||
FileStream::Context::Context(const scoped_refptr<base::TaskRunner>& task_runner)
|
FileStream::Context::Context(scoped_refptr<base::TaskRunner> task_runner)
|
||||||
: async_in_progress_(false),
|
: Context(base::File(), std::move(task_runner)) {}
|
||||||
orphaned_(false),
|
|
||||||
task_runner_(task_runner) {
|
|
||||||
}
|
|
||||||
|
|
||||||
FileStream::Context::Context(base::File file,
|
FileStream::Context::Context(base::File file,
|
||||||
const scoped_refptr<base::TaskRunner>& task_runner)
|
scoped_refptr<base::TaskRunner> task_runner)
|
||||||
: file_(std::move(file)),
|
: file_(std::move(file)), task_runner_(std::move(task_runner)) {}
|
||||||
async_in_progress_(false),
|
|
||||||
orphaned_(false),
|
|
||||||
task_runner_(task_runner) {}
|
|
||||||
|
|
||||||
FileStream::Context::~Context() = default;
|
FileStream::Context::~Context() = default;
|
||||||
|
|
||||||
|
@ -38,25 +38,14 @@ void IncrementOffset(OVERLAPPED* overlapped, DWORD count) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
FileStream::Context::Context(const scoped_refptr<base::TaskRunner>& task_runner)
|
FileStream::Context::Context(scoped_refptr<base::TaskRunner> task_runner)
|
||||||
: async_in_progress_(false),
|
: Context(base::File(), std::move(task_runner)) {}
|
||||||
orphaned_(false),
|
|
||||||
task_runner_(task_runner),
|
|
||||||
async_read_initiated_(false),
|
|
||||||
async_read_completed_(false),
|
|
||||||
io_complete_for_read_received_(false),
|
|
||||||
result_(0) {}
|
|
||||||
|
|
||||||
FileStream::Context::Context(base::File file,
|
FileStream::Context::Context(base::File file,
|
||||||
const scoped_refptr<base::TaskRunner>& task_runner)
|
scoped_refptr<base::TaskRunner> task_runner)
|
||||||
: file_(std::move(file)),
|
: base::MessagePumpForIO::IOHandler(FROM_HERE),
|
||||||
async_in_progress_(false),
|
file_(std::move(file)),
|
||||||
orphaned_(false),
|
task_runner_(std::move(task_runner)) {
|
||||||
task_runner_(task_runner),
|
|
||||||
async_read_initiated_(false),
|
|
||||||
async_read_completed_(false),
|
|
||||||
io_complete_for_read_received_(false),
|
|
||||||
result_(0) {
|
|
||||||
if (file_.IsValid()) {
|
if (file_.IsValid()) {
|
||||||
DCHECK(file_.async());
|
DCHECK(file_.async());
|
||||||
OnFileOpened();
|
OnFileOpened();
|
||||||
|
@ -40,7 +40,7 @@ static_assert(offsetof(MyOverlapped, context_) == 0,
|
|||||||
class CompletionHandler : public base::MessagePumpForIO::IOHandler,
|
class CompletionHandler : public base::MessagePumpForIO::IOHandler,
|
||||||
public base::RefCounted<CompletionHandler> {
|
public base::RefCounted<CompletionHandler> {
|
||||||
public:
|
public:
|
||||||
CompletionHandler() = default;
|
CompletionHandler() : base::MessagePumpForIO::IOHandler(FROM_HERE) {}
|
||||||
static CompletionHandler* Get();
|
static CompletionHandler* Get();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -114,34 +114,34 @@ class WtsSessionProcessDelegate::Core
|
|||||||
void ReportProcessLaunched(base::win::ScopedHandle worker_process);
|
void ReportProcessLaunched(base::win::ScopedHandle worker_process);
|
||||||
|
|
||||||
// The task runner all public methods of this class should be called on.
|
// The task runner all public methods of this class should be called on.
|
||||||
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
|
const scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
|
||||||
|
|
||||||
// The task runner serving job object notifications.
|
// The task runner serving job object notifications.
|
||||||
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
|
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
|
||||||
|
|
||||||
// The server end of the IPC channel used to communicate to the worker
|
// The server end of the IPC channel used to communicate to the worker
|
||||||
// process.
|
// process.
|
||||||
std::unique_ptr<IPC::ChannelProxy> channel_;
|
std::unique_ptr<IPC::ChannelProxy> channel_;
|
||||||
|
|
||||||
// Security descriptor (as SDDL) to be applied to |channel_|.
|
// Security descriptor (as SDDL) to be applied to |channel_|.
|
||||||
std::string channel_security_;
|
const std::string channel_security_;
|
||||||
|
|
||||||
WorkerProcessLauncher* event_handler_;
|
WorkerProcessLauncher* event_handler_ = nullptr;
|
||||||
|
|
||||||
// The job object used to control the lifetime of child processes.
|
// The job object used to control the lifetime of child processes.
|
||||||
base::win::ScopedHandle job_;
|
base::win::ScopedHandle job_;
|
||||||
|
|
||||||
// True if the worker process should be launched elevated.
|
// True if the worker process should be launched elevated.
|
||||||
bool launch_elevated_;
|
const bool launch_elevated_;
|
||||||
|
|
||||||
// True if a laucnh attemp is pending.
|
// True if a launch attempt is pending.
|
||||||
bool launch_pending_;
|
bool launch_pending_ = false;
|
||||||
|
|
||||||
// The token to be used to launch a process in a different session.
|
// The token to be used to launch a process in a different session.
|
||||||
base::win::ScopedHandle session_token_;
|
base::win::ScopedHandle session_token_;
|
||||||
|
|
||||||
// Command line of the launched process.
|
// Command line of the launched process.
|
||||||
std::unique_ptr<base::CommandLine> target_command_;
|
const std::unique_ptr<base::CommandLine> target_command_;
|
||||||
|
|
||||||
// The handle of the worker process, if launched.
|
// The handle of the worker process, if launched.
|
||||||
base::win::ScopedHandle worker_process_;
|
base::win::ScopedHandle worker_process_;
|
||||||
@ -167,12 +167,11 @@ WtsSessionProcessDelegate::Core::Core(
|
|||||||
std::unique_ptr<base::CommandLine> target_command,
|
std::unique_ptr<base::CommandLine> target_command,
|
||||||
bool launch_elevated,
|
bool launch_elevated,
|
||||||
const std::string& channel_security)
|
const std::string& channel_security)
|
||||||
: caller_task_runner_(base::ThreadTaskRunnerHandle::Get()),
|
: base::MessagePumpForIO::IOHandler(FROM_HERE),
|
||||||
io_task_runner_(io_task_runner),
|
caller_task_runner_(base::ThreadTaskRunnerHandle::Get()),
|
||||||
|
io_task_runner_(std::move(io_task_runner)),
|
||||||
channel_security_(channel_security),
|
channel_security_(channel_security),
|
||||||
event_handler_(nullptr),
|
|
||||||
launch_elevated_(launch_elevated),
|
launch_elevated_(launch_elevated),
|
||||||
launch_pending_(false),
|
|
||||||
target_command_(std::move(target_command)) {}
|
target_command_(std::move(target_command)) {}
|
||||||
|
|
||||||
bool WtsSessionProcessDelegate::Core::Initialize(uint32_t session_id) {
|
bool WtsSessionProcessDelegate::Core::Initialize(uint32_t session_id) {
|
||||||
|
@ -358,9 +358,7 @@ SerialIoHandlerWin::SerialIoHandlerWin(
|
|||||||
const base::FilePath& port,
|
const base::FilePath& port,
|
||||||
scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner)
|
scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner)
|
||||||
: SerialIoHandler(port, std::move(ui_thread_task_runner)),
|
: SerialIoHandler(port, std::move(ui_thread_task_runner)),
|
||||||
event_mask_(0),
|
base::MessagePumpForIO::IOHandler(FROM_HERE) {}
|
||||||
is_comm_pending_(false),
|
|
||||||
helper_(nullptr) {}
|
|
||||||
|
|
||||||
SerialIoHandlerWin::~SerialIoHandlerWin() {
|
SerialIoHandlerWin::~SerialIoHandlerWin() {
|
||||||
ui_thread_task_runner()->DeleteSoon(FROM_HERE, helper_);
|
ui_thread_task_runner()->DeleteSoon(FROM_HERE, helper_);
|
||||||
|
@ -59,16 +59,16 @@ class SerialIoHandlerWin : public SerialIoHandler,
|
|||||||
std::unique_ptr<base::MessagePumpForIO::IOContext> write_context_;
|
std::unique_ptr<base::MessagePumpForIO::IOContext> write_context_;
|
||||||
|
|
||||||
// Asynchronous event mask state
|
// Asynchronous event mask state
|
||||||
DWORD event_mask_;
|
DWORD event_mask_ = 0;
|
||||||
|
|
||||||
// Indicates if a pending read is waiting on initial data arrival via
|
// Indicates if a pending read is waiting on initial data arrival via
|
||||||
// WaitCommEvent, as opposed to waiting on actual ReadFile completion
|
// WaitCommEvent, as opposed to waiting on actual ReadFile completion
|
||||||
// after a corresponding WaitCommEvent has completed.
|
// after a corresponding WaitCommEvent has completed.
|
||||||
bool is_comm_pending_;
|
bool is_comm_pending_ = false;
|
||||||
|
|
||||||
// The helper lives on the UI thread and holds a weak reference back to the
|
// The helper lives on the UI thread and holds a weak reference back to the
|
||||||
// handler that owns it.
|
// handler that owns it.
|
||||||
UiThreadHelper* helper_;
|
UiThreadHelper* helper_ = nullptr;
|
||||||
base::WeakPtrFactory<SerialIoHandlerWin> weak_factory_{this};
|
base::WeakPtrFactory<SerialIoHandlerWin> weak_factory_{this};
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(SerialIoHandlerWin);
|
DISALLOW_COPY_AND_ASSIGN(SerialIoHandlerWin);
|
||||||
|
Reference in New Issue
Block a user