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"
9 AsyncSocketIoHandler::AsyncSocketIoHandler()
10 : socket_(base::SyncSocket::kInvalidHandle
),
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());
21 // Make the context be deleted by the message pump when done.
22 context_
->handler
= NULL
;
29 // Implementation of IOHandler on Windows.
30 void AsyncSocketIoHandler::OnIOCompleted(
31 base::MessageLoopForIO::IOContext
* context
,
32 DWORD bytes_transfered
,
34 DCHECK(CalledOnValidThread());
35 DCHECK_EQ(context_
, context
);
36 DCHECK(!read_complete_
.is_null());
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());
45 DCHECK_NE(socket_
, base::SyncSocket::kInvalidHandle
);
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
) {
61 DCHECK_EQ(socket_
, base::SyncSocket::kInvalidHandle
);
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
));