Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / base / async_socket_io_handler_win.cc
blobe1d215c980af69eec8e1358452a6f53d4b73fa32
1 // Copyright 2013 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.
5 #include "base/async_socket_io_handler.h"
7 namespace base {
9 AsyncSocketIoHandler::AsyncSocketIoHandler()
10 : socket_(base::SyncSocket::kInvalidHandle),
11 context_(NULL),
12 is_pending_(false) {}
14 AsyncSocketIoHandler::~AsyncSocketIoHandler() {
15 // We need to be deleted on the correct thread to avoid racing with the
16 // message loop thread.
17 DCHECK(CalledOnValidThread());
19 if (context_) {
20 if (is_pending_) {
21 // Make the context be deleted by the message pump when done.
22 context_->handler = NULL;
23 } else {
24 delete context_;
29 // Implementation of IOHandler on Windows.
30 void AsyncSocketIoHandler::OnIOCompleted(
31 base::MessageLoopForIO::IOContext* context,
32 DWORD bytes_transfered,
33 DWORD error) {
34 DCHECK(CalledOnValidThread());
35 DCHECK_EQ(context_, context);
36 DCHECK(!read_complete_.is_null());
37 is_pending_ = false;
38 read_complete_.Run(error == ERROR_SUCCESS ? bytes_transfered : 0);
41 bool AsyncSocketIoHandler::Read(char* buffer, int buffer_len) {
42 DCHECK(CalledOnValidThread());
43 DCHECK(!read_complete_.is_null());
44 DCHECK(!is_pending_);
45 DCHECK_NE(socket_, base::SyncSocket::kInvalidHandle);
47 DWORD bytes_read = 0;
48 BOOL ok = ::ReadFile(socket_, buffer, buffer_len, &bytes_read,
49 &context_->overlapped);
50 // The completion port will be signaled regardless of completing the read
51 // straight away or asynchronously (ERROR_IO_PENDING). OnIOCompleted() will
52 // be called regardless and we don't need to explicitly run the callback
53 // in the case where ok is FALSE and GLE==ERROR_IO_PENDING.
54 is_pending_ = !ok && (GetLastError() == ERROR_IO_PENDING);
55 return ok || is_pending_;
58 bool AsyncSocketIoHandler::Initialize(base::SyncSocket::Handle socket,
59 const ReadCompleteCallback& callback) {
60 DCHECK(!context_);
61 DCHECK_EQ(socket_, base::SyncSocket::kInvalidHandle);
63 DetachFromThread();
65 socket_ = socket;
66 read_complete_ = callback;
68 base::MessageLoopForIO::current()->RegisterIOHandler(socket, this);
70 context_ = new base::MessageLoopForIO::IOContext();
71 context_->handler = this;
72 memset(&context_->overlapped, 0, sizeof(context_->overlapped));
74 return true;
77 } // namespace base.