Avoid windows.h in message_pump_win.h.
This was used to define OVERLAPPED. Instead, make a duplicate definition and use it to create properly-sized/aligned storage, that a real obj can be constructed in in the .cc file. Bug: 364987728 Change-Id: I0bffb42304659cce29807ab8af6070f9653b32f6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6134189 Auto-Submit: Peter Kasting <pkasting@chromium.org> Reviewed-by: Nico Weber <thakis@chromium.org> Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com> Owners-Override: Nico Weber <thakis@chromium.org> Commit-Queue: Peter Kasting <pkasting@chromium.org> Cr-Commit-Position: refs/heads/main@{#1401181}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
8b592906df
commit
47b48940fb
base
components/wifi
mojo/core
net
base
disk_cache
blockfile
socket
remoting/host
services/device/serial
@ -9,6 +9,7 @@
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#include "base/auto_reset.h"
|
||||
@ -719,7 +720,18 @@ bool MessagePumpForUI::ProcessPumpReplacementMessage() {
|
||||
// MessagePumpForIO public:
|
||||
|
||||
MessagePumpForIO::IOContext::IOContext() {
|
||||
memset(&overlapped, 0, sizeof(overlapped));
|
||||
std::construct_at(GetOverlapped());
|
||||
std::memset(GetOverlapped(), 0, sizeof(OVERLAPPED));
|
||||
}
|
||||
|
||||
MessagePumpForIO::IOContext::~IOContext() {
|
||||
std::destroy_at(GetOverlapped());
|
||||
}
|
||||
|
||||
OVERLAPPED* MessagePumpForIO::IOContext::GetOverlapped() {
|
||||
static_assert(sizeof(OVERLAPPED) == sizeof(Sizer));
|
||||
static_assert(alignof(OVERLAPPED) == alignof(Sizer));
|
||||
return reinterpret_cast<OVERLAPPED*>(storage_);
|
||||
}
|
||||
|
||||
MessagePumpForIO::IOHandler::IOHandler(const Location& from_here)
|
||||
|
@ -5,8 +5,6 @@
|
||||
#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_
|
||||
#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_WIN_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@ -22,6 +20,7 @@
|
||||
#include "base/time/time.h"
|
||||
#include "base/win/message_window.h"
|
||||
#include "base/win/scoped_handle.h"
|
||||
#include "base/win/windows_types.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
@ -219,9 +218,35 @@ class BASE_EXPORT MessagePumpForUI : public MessagePumpWin {
|
||||
//
|
||||
class BASE_EXPORT MessagePumpForIO : public MessagePumpWin {
|
||||
public:
|
||||
struct BASE_EXPORT IOContext {
|
||||
class BASE_EXPORT IOContext {
|
||||
public:
|
||||
IOContext();
|
||||
OVERLAPPED overlapped;
|
||||
~IOContext();
|
||||
|
||||
OVERLAPPED* GetOverlapped();
|
||||
|
||||
private:
|
||||
// Hack: This header needs to be pulled in by files that should not
|
||||
// `#include <windows.h>`, yet wants to store an `OVERLAPPED` inline.
|
||||
// We can't simply define `OVERLAPPED` ourselves, or the compiler will
|
||||
// complain about type redefinitions in files that _do_ see the real
|
||||
// definition. Instead, define an identical struct, but use it only to
|
||||
// align/size storage that we will construct a real `OVERLAPPED` in in the
|
||||
// constructor.
|
||||
struct Sizer {
|
||||
ULONG_PTR Internal;
|
||||
ULONG_PTR InternalHigh;
|
||||
union {
|
||||
struct {
|
||||
DWORD Offset;
|
||||
DWORD OffsetHigh;
|
||||
} DUMMYSTRUCTNAME;
|
||||
PVOID Pointer;
|
||||
} DUMMYUNIONNAME;
|
||||
HANDLE hEvent;
|
||||
};
|
||||
|
||||
alignas(Sizer) unsigned char storage_[sizeof(Sizer)];
|
||||
};
|
||||
|
||||
// Clients interested in receiving OS notifications when asynchronous IO
|
||||
|
@ -411,7 +411,7 @@ class TestIOHandler : public MessagePumpForIO::IOHandler {
|
||||
DWORD error) override;
|
||||
|
||||
void Init();
|
||||
OVERLAPPED* context() { return &context_.overlapped; }
|
||||
OVERLAPPED* context() { return context_.GetOverlapped(); }
|
||||
DWORD size() { return sizeof(buffer_); }
|
||||
|
||||
private:
|
||||
|
@ -28,6 +28,8 @@
|
||||
|
||||
#if BUILDFLAG(IS_APPLE)
|
||||
#include "base/apple/scoped_nsautorelease_pool.h"
|
||||
#elif BUILDFLAG(IS_WIN)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace wifi {
|
||||
|
@ -306,7 +306,7 @@ class ChannelWin : public Channel,
|
||||
|
||||
BOOL ok =
|
||||
::ReadFile(handle_.get(), buffer, static_cast<DWORD>(buffer_capacity),
|
||||
NULL, &read_context_.overlapped);
|
||||
NULL, read_context_.GetOverlapped());
|
||||
if (ok || GetLastError() == ERROR_IO_PENDING) {
|
||||
is_read_pending_ = true;
|
||||
AddRef();
|
||||
@ -336,7 +336,7 @@ class ChannelWin : public Channel,
|
||||
DCHECK(handle_.is_valid());
|
||||
BOOL ok = WriteFile(handle_.get(), message->data(),
|
||||
static_cast<DWORD>(message->data_num_bytes()), NULL,
|
||||
&write_context_.overlapped);
|
||||
write_context_.GetOverlapped());
|
||||
if (ok || GetLastError() == ERROR_IO_PENDING) {
|
||||
is_write_pending_ = true;
|
||||
AddRef();
|
||||
|
@ -20,6 +20,10 @@
|
||||
#include "net/base/apple/guarded_fd.h"
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace net {
|
||||
|
||||
namespace {
|
||||
|
@ -72,7 +72,7 @@ int FileStream::Context::Read(IOBuffer* buf,
|
||||
FROM_HERE,
|
||||
base::BindOnce(&FileStream::Context::ReadAsync, base::Unretained(this),
|
||||
file_.GetPlatformFile(), base::WrapRefCounted(buf),
|
||||
buf_len, &io_context_.overlapped,
|
||||
buf_len, io_context_.GetOverlapped(),
|
||||
base::SingleThreadTaskRunner::GetCurrentDefault()));
|
||||
return ERR_IO_PENDING;
|
||||
}
|
||||
@ -85,8 +85,8 @@ int FileStream::Context::Write(IOBuffer* buf,
|
||||
result_ = 0;
|
||||
|
||||
DWORD bytes_written = 0;
|
||||
if (!WriteFile(file_.GetPlatformFile(), buf->data(), buf_len,
|
||||
&bytes_written, &io_context_.overlapped)) {
|
||||
if (!WriteFile(file_.GetPlatformFile(), buf->data(), buf_len, &bytes_written,
|
||||
io_context_.GetOverlapped())) {
|
||||
IOResult error = IOResult::FromOSError(GetLastError());
|
||||
if (error.os_error == ERROR_IO_PENDING) {
|
||||
IOCompletionIsPending(std::move(callback), buf);
|
||||
@ -105,7 +105,7 @@ int FileStream::Context::ConnectNamedPipe(CompletionOnceCallback callback) {
|
||||
|
||||
result_ = 0;
|
||||
// Always returns zero when making an asynchronous call.
|
||||
::ConnectNamedPipe(file_.GetPlatformFile(), &io_context_.overlapped);
|
||||
::ConnectNamedPipe(file_.GetPlatformFile(), io_context_.GetOverlapped());
|
||||
const auto error = ::GetLastError();
|
||||
if (error == ERROR_PIPE_CONNECTED) {
|
||||
return OK; // The client has already connected; operation complete.
|
||||
@ -124,7 +124,7 @@ FileStream::Context::IOResult FileStream::Context::SeekFileImpl(
|
||||
int64_t offset) {
|
||||
LARGE_INTEGER result;
|
||||
result.QuadPart = offset;
|
||||
SetOffset(&io_context_.overlapped, result);
|
||||
SetOffset(io_context_.GetOverlapped(), result);
|
||||
return IOResult(result.QuadPart, 0);
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ void FileStream::Context::OnIOCompleted(
|
||||
if (result_)
|
||||
DCHECK_EQ(result_, static_cast<int>(bytes_read));
|
||||
result_ = bytes_read;
|
||||
IncrementOffset(&io_context_.overlapped, bytes_read);
|
||||
IncrementOffset(io_context_.GetOverlapped(), bytes_read);
|
||||
}
|
||||
|
||||
if (async_read_initiated_)
|
||||
|
@ -47,6 +47,10 @@ using net::test::IsOk;
|
||||
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
#include "base/test/test_file_util.h"
|
||||
#elif BUILDFLAG(IS_WIN)
|
||||
#include <windows.h>
|
||||
|
||||
#include <namedpipeapi.h>
|
||||
#endif
|
||||
|
||||
namespace net {
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include "net/disk_cache/blockfile/file.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <utility>
|
||||
@ -29,10 +31,8 @@ class CompletionHandler;
|
||||
struct MyOverlapped {
|
||||
MyOverlapped(disk_cache::File* file, size_t offset,
|
||||
disk_cache::FileIOCallback* callback);
|
||||
~MyOverlapped() {}
|
||||
OVERLAPPED* overlapped() {
|
||||
return &context_.overlapped;
|
||||
}
|
||||
~MyOverlapped() = default;
|
||||
OVERLAPPED* overlapped() { return context_.GetOverlapped(); }
|
||||
|
||||
base::MessagePumpForIO::IOContext context_;
|
||||
scoped_refptr<disk_cache::File> file_;
|
||||
@ -90,7 +90,7 @@ void CompletionHandler::OnIOCompleted(
|
||||
|
||||
MyOverlapped::MyOverlapped(disk_cache::File* file, size_t offset,
|
||||
disk_cache::FileIOCallback* callback) {
|
||||
context_.overlapped.Offset = static_cast<DWORD>(offset);
|
||||
context_.GetOverlapped()->Offset = static_cast<DWORD>(offset);
|
||||
file_ = file;
|
||||
callback_ = callback;
|
||||
completion_handler_ = CompletionHandler::Get();
|
||||
|
@ -298,7 +298,7 @@ int TcpSocketIoCompletionPortWin::Write(
|
||||
|
||||
const int rv =
|
||||
::WSASend(socket_, &write_buffer, /*dwBufferCount=*/1, &bytes_sent,
|
||||
/*dwFlags=*/0, &context->overlapped,
|
||||
/*dwFlags=*/0, context->GetOverlapped(),
|
||||
/*lpCompletionRoutine=*/nullptr);
|
||||
|
||||
// "Citations" below are from
|
||||
@ -508,7 +508,7 @@ int TcpSocketIoCompletionPortWin::HandleReadRequest(
|
||||
// whether zero-byte overlapped reads are allowed (for ReadIfReady).
|
||||
auto rv = ::WSARecv(
|
||||
socket_, &read_buffer, /*dwBufferCount=*/1, &bytes_read, &flags,
|
||||
allow_zero_byte_overlapped_read ? nullptr : &context->overlapped,
|
||||
allow_zero_byte_overlapped_read ? nullptr : context->GetOverlapped(),
|
||||
nullptr);
|
||||
|
||||
// "Citations" below are from
|
||||
@ -532,7 +532,7 @@ int TcpSocketIoCompletionPortWin::HandleReadRequest(
|
||||
// value from WSARecv here in that case will be WSA_IO_PENDING.
|
||||
read_buffer = {};
|
||||
rv = ::WSARecv(socket_, &read_buffer, /*dwBufferCount=*/1, &bytes_read,
|
||||
&flags, &context->overlapped, nullptr);
|
||||
&flags, context->GetOverlapped(), nullptr);
|
||||
if (rv == 0) {
|
||||
// Immediate completion for zero-byte read. The contract for ReadIfReady
|
||||
// explicitly states that on synchronous completion we need to return
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "remoting/host/desktop_session_agent.h"
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include <windows.h>
|
||||
|
||||
#include "base/win/windows_version.h"
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
|
||||
|
@ -194,7 +194,7 @@ void SerialIoHandlerWin::ReadImpl() {
|
||||
|
||||
if (!ReadFile(file().GetPlatformFile(), pending_read_buffer().data(),
|
||||
pending_read_buffer().size(), nullptr,
|
||||
&read_context_->overlapped) &&
|
||||
read_context_->GetOverlapped()) &&
|
||||
GetLastError() != ERROR_IO_PENDING) {
|
||||
OnIOCompleted(read_context_.get(), 0, GetLastError());
|
||||
}
|
||||
@ -206,7 +206,7 @@ void SerialIoHandlerWin::WriteImpl() {
|
||||
|
||||
if (!WriteFile(file().GetPlatformFile(), pending_write_buffer().data(),
|
||||
pending_write_buffer().size(), nullptr,
|
||||
&write_context_->overlapped) &&
|
||||
write_context_->GetOverlapped()) &&
|
||||
GetLastError() != ERROR_IO_PENDING) {
|
||||
OnIOCompleted(write_context_.get(), 0, GetLastError());
|
||||
}
|
||||
|
Reference in New Issue
Block a user