[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)
|
||||
: signal_(signal), wait_(wait) {
|
||||
: MessagePumpForIO::IOHandler(FROM_HERE), signal_(signal), wait_(wait) {
|
||||
memset(buffer_, 0, sizeof(buffer_));
|
||||
|
||||
file_.Set(CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
|
||||
|
@ -544,6 +544,11 @@ MessagePumpForIO::IOContext::IOContext() {
|
||||
memset(&overlapped, 0, sizeof(overlapped));
|
||||
}
|
||||
|
||||
MessagePumpForIO::IOHandler::IOHandler(const Location& from_here)
|
||||
: io_handler_location_(from_here) {}
|
||||
|
||||
MessagePumpForIO::IOHandler::~IOHandler() = default;
|
||||
|
||||
MessagePumpForIO::MessagePumpForIO() {
|
||||
port_.Set(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr,
|
||||
reinterpret_cast<ULONG_PTR>(nullptr), 1));
|
||||
@ -678,6 +683,9 @@ bool MessagePumpForIO::WaitForIOCompletion(DWORD timeout, IOHandler* filter) {
|
||||
// Save this item for later
|
||||
completed_io_.push_back(item);
|
||||
} 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.error);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "base/base_export.h"
|
||||
#include "base/location.h"
|
||||
#include "base/message_loop/message_pump.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "base/optional.h"
|
||||
@ -198,7 +199,7 @@ class BASE_EXPORT MessagePumpForIO : public MessagePumpWin {
|
||||
//
|
||||
// Typical use #1:
|
||||
// class MyFile : public IOHandler {
|
||||
// MyFile() {
|
||||
// MyFile() : IOHandler(FROM_HERE) {
|
||||
// ...
|
||||
// message_pump->RegisterIOHandler(file_, this);
|
||||
// }
|
||||
@ -228,9 +229,14 @@ class BASE_EXPORT MessagePumpForIO : public MessagePumpWin {
|
||||
// message_pump->WaitForIOCompletion(INFINITE, this);
|
||||
// }
|
||||
//
|
||||
class IOHandler {
|
||||
class BASE_EXPORT IOHandler {
|
||||
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
|
||||
// |context| completes. |error| is the Win32 error code of the IO operation
|
||||
// (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,
|
||||
DWORD bytes_transfered,
|
||||
DWORD error) = 0;
|
||||
|
||||
const Location& io_handler_location() { return io_handler_location_; }
|
||||
|
||||
private:
|
||||
const Location io_handler_location_;
|
||||
};
|
||||
|
||||
MessagePumpForIO();
|
||||
|
@ -85,6 +85,7 @@ class ChannelWin : public Channel,
|
||||
HandlePolicy handle_policy,
|
||||
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
|
||||
: Channel(delegate, handle_policy),
|
||||
base::MessagePumpForIO::IOHandler(FROM_HERE),
|
||||
self_(this),
|
||||
io_task_runner_(io_task_runner) {
|
||||
if (connection_params.server_endpoint().is_valid()) {
|
||||
|
@ -62,8 +62,8 @@ class FileStream::Context {
|
||||
// file_stream_context_{win,posix}.cc.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
explicit Context(const scoped_refptr<base::TaskRunner>& task_runner);
|
||||
Context(base::File file, const scoped_refptr<base::TaskRunner>& task_runner);
|
||||
explicit Context(scoped_refptr<base::TaskRunner> task_runner);
|
||||
Context(base::File file, scoped_refptr<base::TaskRunner> task_runner);
|
||||
#if defined(OS_WIN)
|
||||
~Context() override;
|
||||
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
|
||||
@ -172,7 +172,7 @@ class FileStream::Context {
|
||||
// Deletes an orphaned context.
|
||||
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
|
||||
// thread which is undesirable. To avoid this we execute the ReadFile call
|
||||
// on a worker thread.
|
||||
@ -217,10 +217,10 @@ class FileStream::Context {
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
base::File file_;
|
||||
bool async_in_progress_;
|
||||
bool async_in_progress_ = false;
|
||||
|
||||
bool orphaned_;
|
||||
scoped_refptr<base::TaskRunner> task_runner_;
|
||||
bool orphaned_ = false;
|
||||
const scoped_refptr<base::TaskRunner> task_runner_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
base::MessagePumpForIO::IOContext io_context_;
|
||||
@ -228,16 +228,16 @@ class FileStream::Context {
|
||||
scoped_refptr<IOBuffer> in_flight_buf_;
|
||||
// This flag is set to true when we receive a Read request which is queued to
|
||||
// the thread pool.
|
||||
bool async_read_initiated_;
|
||||
bool async_read_initiated_ = false;
|
||||
// This flag is set to true when we receive a notification ReadAsyncResult()
|
||||
// on the calling thread which indicates that the asynchronous Read
|
||||
// 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
|
||||
// an asynchonously initiated Read operaton. OnIOComplete().
|
||||
bool io_complete_for_read_received_;
|
||||
// an asynchronously initiated Read operation. OnIOComplete().
|
||||
bool io_complete_for_read_received_ = false;
|
||||
// Tracks the result of the IO completion operation. Set in OnIOComplete.
|
||||
int result_;
|
||||
int result_ = 0;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Context);
|
||||
|
@ -21,18 +21,12 @@
|
||||
|
||||
namespace net {
|
||||
|
||||
FileStream::Context::Context(const scoped_refptr<base::TaskRunner>& task_runner)
|
||||
: async_in_progress_(false),
|
||||
orphaned_(false),
|
||||
task_runner_(task_runner) {
|
||||
}
|
||||
FileStream::Context::Context(scoped_refptr<base::TaskRunner> task_runner)
|
||||
: Context(base::File(), std::move(task_runner)) {}
|
||||
|
||||
FileStream::Context::Context(base::File file,
|
||||
const scoped_refptr<base::TaskRunner>& task_runner)
|
||||
: file_(std::move(file)),
|
||||
async_in_progress_(false),
|
||||
orphaned_(false),
|
||||
task_runner_(task_runner) {}
|
||||
scoped_refptr<base::TaskRunner> task_runner)
|
||||
: file_(std::move(file)), task_runner_(std::move(task_runner)) {}
|
||||
|
||||
FileStream::Context::~Context() = default;
|
||||
|
||||
|
@ -38,25 +38,14 @@ void IncrementOffset(OVERLAPPED* overlapped, DWORD count) {
|
||||
|
||||
} // namespace
|
||||
|
||||
FileStream::Context::Context(const scoped_refptr<base::TaskRunner>& task_runner)
|
||||
: async_in_progress_(false),
|
||||
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(scoped_refptr<base::TaskRunner> task_runner)
|
||||
: Context(base::File(), std::move(task_runner)) {}
|
||||
|
||||
FileStream::Context::Context(base::File file,
|
||||
const scoped_refptr<base::TaskRunner>& task_runner)
|
||||
: file_(std::move(file)),
|
||||
async_in_progress_(false),
|
||||
orphaned_(false),
|
||||
task_runner_(task_runner),
|
||||
async_read_initiated_(false),
|
||||
async_read_completed_(false),
|
||||
io_complete_for_read_received_(false),
|
||||
result_(0) {
|
||||
scoped_refptr<base::TaskRunner> task_runner)
|
||||
: base::MessagePumpForIO::IOHandler(FROM_HERE),
|
||||
file_(std::move(file)),
|
||||
task_runner_(std::move(task_runner)) {
|
||||
if (file_.IsValid()) {
|
||||
DCHECK(file_.async());
|
||||
OnFileOpened();
|
||||
|
@ -40,7 +40,7 @@ static_assert(offsetof(MyOverlapped, context_) == 0,
|
||||
class CompletionHandler : public base::MessagePumpForIO::IOHandler,
|
||||
public base::RefCounted<CompletionHandler> {
|
||||
public:
|
||||
CompletionHandler() = default;
|
||||
CompletionHandler() : base::MessagePumpForIO::IOHandler(FROM_HERE) {}
|
||||
static CompletionHandler* Get();
|
||||
|
||||
private:
|
||||
|
@ -114,34 +114,34 @@ class WtsSessionProcessDelegate::Core
|
||||
void ReportProcessLaunched(base::win::ScopedHandle worker_process);
|
||||
|
||||
// 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.
|
||||
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
|
||||
// process.
|
||||
std::unique_ptr<IPC::ChannelProxy> 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.
|
||||
base::win::ScopedHandle job_;
|
||||
|
||||
// True if the worker process should be launched elevated.
|
||||
bool launch_elevated_;
|
||||
const bool launch_elevated_;
|
||||
|
||||
// True if a laucnh attemp is pending.
|
||||
bool launch_pending_;
|
||||
// True if a launch attempt is pending.
|
||||
bool launch_pending_ = false;
|
||||
|
||||
// The token to be used to launch a process in a different session.
|
||||
base::win::ScopedHandle session_token_;
|
||||
|
||||
// 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.
|
||||
base::win::ScopedHandle worker_process_;
|
||||
@ -167,12 +167,11 @@ WtsSessionProcessDelegate::Core::Core(
|
||||
std::unique_ptr<base::CommandLine> target_command,
|
||||
bool launch_elevated,
|
||||
const std::string& channel_security)
|
||||
: caller_task_runner_(base::ThreadTaskRunnerHandle::Get()),
|
||||
io_task_runner_(io_task_runner),
|
||||
: base::MessagePumpForIO::IOHandler(FROM_HERE),
|
||||
caller_task_runner_(base::ThreadTaskRunnerHandle::Get()),
|
||||
io_task_runner_(std::move(io_task_runner)),
|
||||
channel_security_(channel_security),
|
||||
event_handler_(nullptr),
|
||||
launch_elevated_(launch_elevated),
|
||||
launch_pending_(false),
|
||||
target_command_(std::move(target_command)) {}
|
||||
|
||||
bool WtsSessionProcessDelegate::Core::Initialize(uint32_t session_id) {
|
||||
|
@ -358,9 +358,7 @@ SerialIoHandlerWin::SerialIoHandlerWin(
|
||||
const base::FilePath& port,
|
||||
scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner)
|
||||
: SerialIoHandler(port, std::move(ui_thread_task_runner)),
|
||||
event_mask_(0),
|
||||
is_comm_pending_(false),
|
||||
helper_(nullptr) {}
|
||||
base::MessagePumpForIO::IOHandler(FROM_HERE) {}
|
||||
|
||||
SerialIoHandlerWin::~SerialIoHandlerWin() {
|
||||
ui_thread_task_runner()->DeleteSoon(FROM_HERE, helper_);
|
||||
|
@ -59,16 +59,16 @@ class SerialIoHandlerWin : public SerialIoHandler,
|
||||
std::unique_ptr<base::MessagePumpForIO::IOContext> write_context_;
|
||||
|
||||
// Asynchronous event mask state
|
||||
DWORD event_mask_;
|
||||
DWORD event_mask_ = 0;
|
||||
|
||||
// Indicates if a pending read is waiting on initial data arrival via
|
||||
// WaitCommEvent, as opposed to waiting on actual ReadFile completion
|
||||
// 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
|
||||
// handler that owns it.
|
||||
UiThreadHelper* helper_;
|
||||
UiThreadHelper* helper_ = nullptr;
|
||||
base::WeakPtrFactory<SerialIoHandlerWin> weak_factory_{this};
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(SerialIoHandlerWin);
|
||||
|
Reference in New Issue
Block a user