blob: a16a2dea5f03d19be7c18ea228ec2b6f774df7da [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_SOCKET_TCP_SOCKET_IO_COMPLETION_PORT_WIN_H_
#define NET_SOCKET_TCP_SOCKET_IO_COMPLETION_PORT_WIN_H_
#include <memory>
#include "base/win/windows_types.h"
#include "net/base/net_export.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/tcp_socket_win.h"
namespace net {
class NetLog;
struct NetLogSource;
class SocketPerformanceWatcher;
// An implementation of TCPSocketWin which uses an IO completion port to be
// notified of completed reads and writes. The goal is to avoid the PostTask
// overhead associated with the use of base::ObjectWatcher in
// TCPSocketDefaultWin.
class NET_EXPORT TcpSocketIoCompletionPortWin : public TCPSocketWin {
public:
// Disables usage of FILE_SKIP_COMPLETION_PORT_ON_SUCCESS in a scope. This
// only affect sockets on which `Read()` or `Write()` hasn't been called yet.
class NET_EXPORT DisableSkipCompletionPortOnSuccessForTesting {
public:
DisableSkipCompletionPortOnSuccessForTesting();
~DisableSkipCompletionPortOnSuccessForTesting();
DisableSkipCompletionPortOnSuccessForTesting(
const DisableSkipCompletionPortOnSuccessForTesting&) = delete;
DisableSkipCompletionPortOnSuccessForTesting& operator=(
const DisableSkipCompletionPortOnSuccessForTesting&) = delete;
};
TcpSocketIoCompletionPortWin(
std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
NetLog* net_log,
const NetLogSource& source);
TcpSocketIoCompletionPortWin(
std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
NetLogWithSource net_log_source);
~TcpSocketIoCompletionPortWin() override;
// TCPSocketWin:
int Read(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) override;
int ReadIfReady(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) override;
int CancelReadIfReady() override;
int Write(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback,
const NetworkTrafficAnnotationTag& traffic_annotation) override;
protected:
// TCPSocketWin:
scoped_refptr<Core> CreateCore() override;
bool HasPendingRead() const override;
void OnClosed() override;
private:
class CoreImpl;
// Ensures that overlapped IO is initialized for `socket_`. This entails:
// - Registering `core_` as an IO handler.
// - Attempting to activate `FILE_SKIP_COMPLETION_PORT_ON_SUCCESS`.
void EnsureOverlappedIOInitialized();
// Handles a completed read/write operation on `socket_`. `bytes_transferred`
// is the number of bytes actually read/written. `error` is the error code for
// the operation. `buffer` is the buffer used to initiate the read/write
// operation and `buffer_length` is its size (`bytes_transferred` should be <=
// `buffer_length`). Returns the value to pass to the completion callback
// associated with the operation (<0 is an error code, >=0 is a number of
// bytes transferred).
int DidCompleteRead(DWORD bytes_transferred,
DWORD error,
scoped_refptr<IOBuffer> buffer,
int buffer_length);
int DidCompleteWrite(DWORD bytes_transferred,
DWORD error,
scoped_refptr<IOBuffer> buffer,
int buffer_length);
CoreImpl& GetCoreImpl();
// Number of read operations waiting for an I/O completion packet.
int num_pending_reads_ = 0;
// Whether queuing a completion packet is skipped when an operation on
// `socket_` succeeds immediately.
bool skip_completion_port_on_success_ = false;
};
} // namespace net
#endif // NET_SOCKET_TCP_SOCKET_IO_COMPLETION_PORT_WIN_H_