Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: net/udp/udp_socket_win.cc

Issue 10918158: [net/udp] Create UDPSocketWin::Core which persists until all network operations complete. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: respond to review Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/udp/udp_socket_win.h" 5 #include "net/udp/udp_socket_win.h"
6 6
7 #include <mstcpip.h> 7 #include <mstcpip.h>
8 8
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/eintr_wrapper.h" 10 #include "base/eintr_wrapper.h"
(...skipping 13 matching lines...) Expand all
24 namespace { 24 namespace {
25 25
26 static const int kBindRetries = 10; 26 static const int kBindRetries = 10;
27 static const int kPortStart = 1024; 27 static const int kPortStart = 1024;
28 static const int kPortEnd = 65535; 28 static const int kPortEnd = 65535;
29 29
30 } // namespace net 30 } // namespace net
31 31
32 namespace net { 32 namespace net {
33 33
34 void UDPSocketWin::ReadDelegate::OnObjectSignaled(HANDLE object) { 34 // This class encapsulates all the state that has to be preserved as long as
35 DCHECK_EQ(object, socket_->read_overlapped_.hEvent); 35 // there is a network IO operation in progress. If the owner UDPSocketWin
36 socket_->DidCompleteRead(); 36 // is destroyed while an operation is in progress, the Core is detached and it
37 // lives until the operation completes and the OS doesn't reference any resource
38 // declared on this class anymore.
39 class UDPSocketWin::Core : public base::RefCounted<Core> {
40 public:
41 explicit Core(UDPSocketWin* socket);
42
43 // Start watching for the end of a read or write operation.
44 void WatchForRead();
45 void WatchForWrite();
46
47 // The UDPSocketWin is going away.
48 void Detach() { socket_ = NULL; }
49
50 // The separate OVERLAPPED variables for asynchronous operation.
51 OVERLAPPED read_overlapped_;
52 OVERLAPPED write_overlapped_;
53
54 // The buffers used in Read() and Write().
55 scoped_refptr<IOBuffer> read_iobuffer_;
56 scoped_refptr<IOBuffer> write_iobuffer_;
57
58 // The address storage passed to WSARecvFrom().
59 SockaddrStorage recv_addr_storage_;
60
61 private:
62 friend class base::RefCounted<Core>;
63
64 class ReadDelegate : public base::win::ObjectWatcher::Delegate {
65 public:
66 explicit ReadDelegate(Core* core) : core_(core) {}
67 virtual ~ReadDelegate() {}
68
69 // base::ObjectWatcher::Delegate methods:
70 virtual void OnObjectSignaled(HANDLE object);
71
72 private:
73 Core* const core_;
74 };
75
76 class WriteDelegate : public base::win::ObjectWatcher::Delegate {
77 public:
78 explicit WriteDelegate(Core* core) : core_(core) {}
79 virtual ~WriteDelegate() {}
80
81 // base::ObjectWatcher::Delegate methods:
82 virtual void OnObjectSignaled(HANDLE object);
83
84 private:
85 Core* const core_;
86 };
87
88 ~Core();
89
90 // The socket that created this object.
91 UDPSocketWin* socket_;
92
93 // |reader_| handles the signals from |read_watcher_|.
94 ReadDelegate reader_;
95 // |writer_| handles the signals from |write_watcher_|.
96 WriteDelegate writer_;
97
98 // |read_watcher_| watches for events from Read().
99 base::win::ObjectWatcher read_watcher_;
100 // |write_watcher_| watches for events from Write();
101 base::win::ObjectWatcher write_watcher_;
102
103 DISALLOW_COPY_AND_ASSIGN(Core);
104 };
105
106 UDPSocketWin::Core::Core(UDPSocketWin* socket)
107 : socket_(socket),
108 ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)),
109 ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)) {
110 memset(&read_overlapped_, 0, sizeof(read_overlapped_));
111 memset(&write_overlapped_, 0, sizeof(write_overlapped_));
112
113 read_overlapped_.hEvent = WSACreateEvent();
114 write_overlapped_.hEvent = WSACreateEvent();
37 } 115 }
38 116
39 void UDPSocketWin::WriteDelegate::OnObjectSignaled(HANDLE object) { 117 UDPSocketWin::Core::~Core() {
40 DCHECK_EQ(object, socket_->write_overlapped_.hEvent); 118 // Make sure the message loop is not watching this object anymore.
41 socket_->DidCompleteWrite(); 119 read_watcher_.StopWatching();
120 write_watcher_.StopWatching();
121
122 WSACloseEvent(read_overlapped_.hEvent);
123 memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_));
124 WSACloseEvent(write_overlapped_.hEvent);
125 memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_));
42 } 126 }
43 127
128 void UDPSocketWin::Core::WatchForRead() {
129 // We grab an extra reference because there is an IO operation in progress.
130 // Balanced in ReadDelegate::OnObjectSignaled().
131 AddRef();
132 read_watcher_.StartWatching(read_overlapped_.hEvent, &reader_);
133 }
134
135 void UDPSocketWin::Core::WatchForWrite() {
136 // We grab an extra reference because there is an IO operation in progress.
137 // Balanced in WriteDelegate::OnObjectSignaled().
138 AddRef();
139 write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_);
140 }
141
142 void UDPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) {
143 DCHECK_EQ(object, core_->read_overlapped_.hEvent);
144 if (core_->socket_)
145 core_->socket_->DidCompleteRead();
146
147 core_->Release();
148 }
149
150 void UDPSocketWin::Core::WriteDelegate::OnObjectSignaled(HANDLE object) {
151 DCHECK_EQ(object, core_->write_overlapped_.hEvent);
152 if (core_->socket_)
153 core_->socket_->DidCompleteWrite();
154
155 core_->Release();
156 }
157
158 //-----------------------------------------------------------------------------
159
44 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, 160 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type,
45 const RandIntCallback& rand_int_cb, 161 const RandIntCallback& rand_int_cb,
46 net::NetLog* net_log, 162 net::NetLog* net_log,
47 const net::NetLog::Source& source) 163 const net::NetLog::Source& source)
48 : socket_(INVALID_SOCKET), 164 : socket_(INVALID_SOCKET),
49 socket_options_(0), 165 socket_options_(0),
50 bind_type_(bind_type), 166 bind_type_(bind_type),
51 rand_int_cb_(rand_int_cb), 167 rand_int_cb_(rand_int_cb),
52 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)),
53 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)),
54 recv_from_address_(NULL), 168 recv_from_address_(NULL),
55 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { 169 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) {
56 EnsureWinsockInit(); 170 EnsureWinsockInit();
57 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, 171 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE,
58 source.ToEventParametersCallback()); 172 source.ToEventParametersCallback());
59 memset(&read_overlapped_, 0, sizeof(read_overlapped_));
60 read_overlapped_.hEvent = WSACreateEvent();
61 memset(&write_overlapped_, 0, sizeof(write_overlapped_));
62 write_overlapped_.hEvent = WSACreateEvent();
63 if (bind_type == DatagramSocket::RANDOM_BIND) 173 if (bind_type == DatagramSocket::RANDOM_BIND)
64 DCHECK(!rand_int_cb.is_null()); 174 DCHECK(!rand_int_cb.is_null());
65 } 175 }
66 176
67 UDPSocketWin::~UDPSocketWin() { 177 UDPSocketWin::~UDPSocketWin() {
68 Close(); 178 Close();
69 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); 179 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE);
70 } 180 }
71 181
72 void UDPSocketWin::Close() { 182 void UDPSocketWin::Close() {
73 DCHECK(CalledOnValidThread()); 183 DCHECK(CalledOnValidThread());
74 184
75 if (!is_connected()) 185 if (!is_connected())
76 return; 186 return;
77 187
78 // Zero out any pending read/write callback state. 188 // Zero out any pending read/write callback state.
79 read_callback_.Reset(); 189 read_callback_.Reset();
80 recv_from_address_ = NULL; 190 recv_from_address_ = NULL;
81 write_callback_.Reset(); 191 write_callback_.Reset();
82 192
83 read_watcher_.StopWatching();
84 write_watcher_.StopWatching();
85
86 WSACloseEvent(read_overlapped_.hEvent);
87 memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_));
88 WSACloseEvent(write_overlapped_.hEvent);
89 memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_));
90
91 closesocket(socket_); 193 closesocket(socket_);
92 socket_ = INVALID_SOCKET; 194 socket_ = INVALID_SOCKET;
195
196 core_->Detach();
197 core_ = NULL;
93 } 198 }
94 199
95 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { 200 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const {
96 DCHECK(CalledOnValidThread()); 201 DCHECK(CalledOnValidThread());
97 DCHECK(address); 202 DCHECK(address);
98 if (!is_connected()) 203 if (!is_connected())
99 return ERR_SOCKET_NOT_CONNECTED; 204 return ERR_SOCKET_NOT_CONNECTED;
100 205
101 // TODO(szym): Simplify. http://crbug.com/126152 206 // TODO(szym): Simplify. http://crbug.com/126152
102 if (!remote_address_.get()) { 207 if (!remote_address_.get()) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 DCHECK_NE(INVALID_SOCKET, socket_); 253 DCHECK_NE(INVALID_SOCKET, socket_);
149 DCHECK(read_callback_.is_null()); 254 DCHECK(read_callback_.is_null());
150 DCHECK(!recv_from_address_); 255 DCHECK(!recv_from_address_);
151 DCHECK(!callback.is_null()); // Synchronous operation not supported. 256 DCHECK(!callback.is_null()); // Synchronous operation not supported.
152 DCHECK_GT(buf_len, 0); 257 DCHECK_GT(buf_len, 0);
153 258
154 int nread = InternalRecvFrom(buf, buf_len, address); 259 int nread = InternalRecvFrom(buf, buf_len, address);
155 if (nread != ERR_IO_PENDING) 260 if (nread != ERR_IO_PENDING)
156 return nread; 261 return nread;
157 262
158 read_iobuffer_ = buf;
159 read_callback_ = callback; 263 read_callback_ = callback;
160 recv_from_address_ = address; 264 recv_from_address_ = address;
161 return ERR_IO_PENDING; 265 return ERR_IO_PENDING;
162 } 266 }
163 267
164 int UDPSocketWin::Write(IOBuffer* buf, 268 int UDPSocketWin::Write(IOBuffer* buf,
165 int buf_len, 269 int buf_len,
166 const CompletionCallback& callback) { 270 const CompletionCallback& callback) {
167 return SendToOrWrite(buf, buf_len, NULL, callback); 271 return SendToOrWrite(buf, buf_len, NULL, callback);
168 } 272 }
(...skipping 15 matching lines...) Expand all
184 DCHECK(!callback.is_null()); // Synchronous operation not supported. 288 DCHECK(!callback.is_null()); // Synchronous operation not supported.
185 DCHECK_GT(buf_len, 0); 289 DCHECK_GT(buf_len, 0);
186 DCHECK(!send_to_address_.get()); 290 DCHECK(!send_to_address_.get());
187 291
188 int nwrite = InternalSendTo(buf, buf_len, address); 292 int nwrite = InternalSendTo(buf, buf_len, address);
189 if (nwrite != ERR_IO_PENDING) 293 if (nwrite != ERR_IO_PENDING)
190 return nwrite; 294 return nwrite;
191 295
192 if (address) 296 if (address)
193 send_to_address_.reset(new IPEndPoint(*address)); 297 send_to_address_.reset(new IPEndPoint(*address));
194 write_iobuffer_ = buf;
195 write_callback_ = callback; 298 write_callback_ = callback;
196 return ERR_IO_PENDING; 299 return ERR_IO_PENDING;
197 } 300 }
198 301
199 int UDPSocketWin::Connect(const IPEndPoint& address) { 302 int UDPSocketWin::Connect(const IPEndPoint& address) {
200 net_log_.BeginEvent(NetLog::TYPE_UDP_CONNECT, 303 net_log_.BeginEvent(NetLog::TYPE_UDP_CONNECT,
201 CreateNetLogUDPConnectCallback(&address)); 304 CreateNetLogUDPConnectCallback(&address));
202 int rv = InternalConnect(address); 305 int rv = InternalConnect(address);
203 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv); 306 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv);
204 return rv; 307 return rv;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 return rv; 346 return rv;
244 local_address_.reset(); 347 local_address_.reset();
245 return rv; 348 return rv;
246 } 349 }
247 350
248 int UDPSocketWin::CreateSocket(const IPEndPoint& address) { 351 int UDPSocketWin::CreateSocket(const IPEndPoint& address) {
249 socket_ = WSASocket(address.GetFamily(), SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 352 socket_ = WSASocket(address.GetFamily(), SOCK_DGRAM, IPPROTO_UDP, NULL, 0,
250 WSA_FLAG_OVERLAPPED); 353 WSA_FLAG_OVERLAPPED);
251 if (socket_ == INVALID_SOCKET) 354 if (socket_ == INVALID_SOCKET)
252 return MapSystemError(WSAGetLastError()); 355 return MapSystemError(WSAGetLastError());
356 core_ = new Core(this);
253 return OK; 357 return OK;
254 } 358 }
255 359
256 bool UDPSocketWin::SetReceiveBufferSize(int32 size) { 360 bool UDPSocketWin::SetReceiveBufferSize(int32 size) {
257 DCHECK(CalledOnValidThread()); 361 DCHECK(CalledOnValidThread());
258 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, 362 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
259 reinterpret_cast<const char*>(&size), sizeof(size)); 363 reinterpret_cast<const char*>(&size), sizeof(size));
260 DCHECK(!rv) << "Could not set socket receive buffer size: " << errno; 364 DCHECK(!rv) << "Could not set socket receive buffer size: " << errno;
261 return rv == 0; 365 return rv == 0;
262 } 366 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 DCHECK(!write_callback_.is_null()); 402 DCHECK(!write_callback_.is_null());
299 403
300 // since Run may result in Write being called, clear write_callback_ up front. 404 // since Run may result in Write being called, clear write_callback_ up front.
301 CompletionCallback c = write_callback_; 405 CompletionCallback c = write_callback_;
302 write_callback_.Reset(); 406 write_callback_.Reset();
303 c.Run(rv); 407 c.Run(rv);
304 } 408 }
305 409
306 void UDPSocketWin::DidCompleteRead() { 410 void UDPSocketWin::DidCompleteRead() {
307 DWORD num_bytes, flags; 411 DWORD num_bytes, flags;
308 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, 412 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_,
309 &num_bytes, FALSE, &flags); 413 &num_bytes, FALSE, &flags);
310 WSAResetEvent(read_overlapped_.hEvent); 414 WSAResetEvent(core_->read_overlapped_.hEvent);
311 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); 415 int result = ok ? num_bytes : MapSystemError(WSAGetLastError());
312 // Convert address. 416 // Convert address.
313 if (recv_from_address_ && result >= 0) { 417 if (recv_from_address_ && result >= 0) {
314 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) 418 if (!ReceiveAddressToIPEndpoint(recv_from_address_))
315 result = ERR_FAILED; 419 result = ERR_FAILED;
316 } 420 }
317 LogRead(result, read_iobuffer_->data()); 421 LogRead(result, core_->read_iobuffer_->data());
318 read_iobuffer_ = NULL; 422 core_->read_iobuffer_ = NULL;
319 recv_from_address_ = NULL; 423 recv_from_address_ = NULL;
320 DoReadCallback(result); 424 DoReadCallback(result);
321 } 425 }
322 426
323 void UDPSocketWin::LogRead(int result, const char* bytes) const { 427 void UDPSocketWin::LogRead(int result, const char* bytes) const {
324 if (result < 0) { 428 if (result < 0) {
325 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); 429 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result);
326 return; 430 return;
327 } 431 }
328 432
329 if (net_log_.IsLoggingAllEvents()) { 433 if (net_log_.IsLoggingAllEvents()) {
330 // Get address for logging, if |address| is NULL. 434 // Get address for logging, if |address| is NULL.
331 IPEndPoint address; 435 IPEndPoint address;
332 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); 436 bool is_address_valid = ReceiveAddressToIPEndpoint(&address);
333 net_log_.AddEvent( 437 net_log_.AddEvent(
334 NetLog::TYPE_UDP_BYTES_RECEIVED, 438 NetLog::TYPE_UDP_BYTES_RECEIVED,
335 CreateNetLogUDPDataTranferCallback( 439 CreateNetLogUDPDataTranferCallback(
336 result, bytes, 440 result, bytes,
337 is_address_valid ? &address : NULL)); 441 is_address_valid ? &address : NULL));
338 } 442 }
339 443
340 base::StatsCounter read_bytes("udp.read_bytes"); 444 base::StatsCounter read_bytes("udp.read_bytes");
341 read_bytes.Add(result); 445 read_bytes.Add(result);
342 } 446 }
343 447
344 void UDPSocketWin::DidCompleteWrite() { 448 void UDPSocketWin::DidCompleteWrite() {
345 DWORD num_bytes, flags; 449 DWORD num_bytes, flags;
346 BOOL ok = WSAGetOverlappedResult(socket_, &write_overlapped_, 450 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_,
347 &num_bytes, FALSE, &flags); 451 &num_bytes, FALSE, &flags);
348 WSAResetEvent(write_overlapped_.hEvent); 452 WSAResetEvent(core_->write_overlapped_.hEvent);
349 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); 453 int result = ok ? num_bytes : MapSystemError(WSAGetLastError());
350 LogWrite(result, write_iobuffer_->data(), send_to_address_.get()); 454 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get());
351 455
352 send_to_address_.reset(); 456 send_to_address_.reset();
353 write_iobuffer_ = NULL; 457 core_->write_iobuffer_ = NULL;
354 DoWriteCallback(result); 458 DoWriteCallback(result);
355 } 459 }
356 460
357 void UDPSocketWin::LogWrite(int result, 461 void UDPSocketWin::LogWrite(int result,
358 const char* bytes, 462 const char* bytes,
359 const IPEndPoint* address) const { 463 const IPEndPoint* address) const {
360 if (result < 0) { 464 if (result < 0) {
361 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); 465 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result);
362 return; 466 return;
363 } 467 }
364 468
365 if (net_log_.IsLoggingAllEvents()) { 469 if (net_log_.IsLoggingAllEvents()) {
366 net_log_.AddEvent( 470 net_log_.AddEvent(
367 NetLog::TYPE_UDP_BYTES_SENT, 471 NetLog::TYPE_UDP_BYTES_SENT,
368 CreateNetLogUDPDataTranferCallback(result, bytes, address)); 472 CreateNetLogUDPDataTranferCallback(result, bytes, address));
369 } 473 }
370 474
371 base::StatsCounter write_bytes("udp.write_bytes"); 475 base::StatsCounter write_bytes("udp.write_bytes");
372 write_bytes.Add(result); 476 write_bytes.Add(result);
373 } 477 }
374 478
375 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, 479 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len,
376 IPEndPoint* address) { 480 IPEndPoint* address) {
377 recv_addr_len_ = sizeof(recv_addr_storage_); 481 DCHECK(!core_->read_iobuffer_);
378 struct sockaddr* addr = 482 SockaddrStorage& storage = core_->recv_addr_storage_;
wtc 2012/09/12 19:07:39 Nit: "recv_addr" is a better name than "storage" f
379 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); 483 storage.addr_len = sizeof(storage.addr_storage);
380 484
381 WSABUF read_buffer; 485 WSABUF read_buffer;
382 read_buffer.buf = buf->data(); 486 read_buffer.buf = buf->data();
383 read_buffer.len = buf_len; 487 read_buffer.len = buf_len;
384 488
385 DWORD flags = 0; 489 DWORD flags = 0;
386 DWORD num; 490 DWORD num;
387 CHECK_NE(INVALID_SOCKET, socket_); 491 CHECK_NE(INVALID_SOCKET, socket_);
388 AssertEventNotSignaled(read_overlapped_.hEvent); 492 AssertEventNotSignaled(core_->read_overlapped_.hEvent);
389 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, addr, 493 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, storage.addr,
390 &recv_addr_len_, &read_overlapped_, NULL); 494 &storage.addr_len, &core_->read_overlapped_, NULL);
391 if (rv == 0) { 495 if (rv == 0) {
392 if (ResetEventIfSignaled(read_overlapped_.hEvent)) { 496 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) {
393 int result = num; 497 int result = num;
394 // Convert address. 498 // Convert address.
395 if (address && result >= 0) { 499 if (address && result >= 0) {
396 if (!ReceiveAddressToIPEndpoint(address)) 500 if (!ReceiveAddressToIPEndpoint(address))
397 result = ERR_FAILED; 501 result = ERR_FAILED;
398 } 502 }
399 LogRead(result, buf->data()); 503 LogRead(result, buf->data());
400 return result; 504 return result;
401 } 505 }
402 } else { 506 } else {
403 int os_error = WSAGetLastError(); 507 int os_error = WSAGetLastError();
404 if (os_error != WSA_IO_PENDING) { 508 if (os_error != WSA_IO_PENDING) {
405 int result = MapSystemError(os_error); 509 int result = MapSystemError(os_error);
406 LogRead(result, NULL); 510 LogRead(result, NULL);
407 return result; 511 return result;
408 } 512 }
409 } 513 }
410 read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_); 514 core_->WatchForRead();
515 core_->read_iobuffer_ = buf;
411 return ERR_IO_PENDING; 516 return ERR_IO_PENDING;
412 } 517 }
413 518
414 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, 519 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len,
415 const IPEndPoint* address) { 520 const IPEndPoint* address) {
521 DCHECK(!core_->write_iobuffer_);
416 SockaddrStorage storage; 522 SockaddrStorage storage;
417 struct sockaddr* addr = storage.addr; 523 struct sockaddr* addr = storage.addr;
418 // Convert address. 524 // Convert address.
419 if (!address) { 525 if (!address) {
420 addr = NULL; 526 addr = NULL;
421 storage.addr_len = 0; 527 storage.addr_len = 0;
422 } else { 528 } else {
423 if (!address->ToSockAddr(addr, &storage.addr_len)) { 529 if (!address->ToSockAddr(addr, &storage.addr_len)) {
424 int result = ERR_FAILED; 530 int result = ERR_FAILED;
425 LogWrite(result, NULL, NULL); 531 LogWrite(result, NULL, NULL);
426 return result; 532 return result;
427 } 533 }
428 } 534 }
429 535
430 WSABUF write_buffer; 536 WSABUF write_buffer;
431 write_buffer.buf = buf->data(); 537 write_buffer.buf = buf->data();
432 write_buffer.len = buf_len; 538 write_buffer.len = buf_len;
433 539
434 DWORD flags = 0; 540 DWORD flags = 0;
435 DWORD num; 541 DWORD num;
436 AssertEventNotSignaled(write_overlapped_.hEvent); 542 AssertEventNotSignaled(core_->write_overlapped_.hEvent);
437 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, 543 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags,
438 addr, storage.addr_len, &write_overlapped_, NULL); 544 addr, storage.addr_len, &core_->write_overlapped_, NULL);
439 if (rv == 0) { 545 if (rv == 0) {
440 if (ResetEventIfSignaled(write_overlapped_.hEvent)) { 546 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) {
441 int result = num; 547 int result = num;
442 LogWrite(result, buf->data(), address); 548 LogWrite(result, buf->data(), address);
443 return result; 549 return result;
444 } 550 }
445 } else { 551 } else {
446 int os_error = WSAGetLastError(); 552 int os_error = WSAGetLastError();
447 if (os_error != WSA_IO_PENDING) { 553 if (os_error != WSA_IO_PENDING) {
448 int result = MapSystemError(os_error); 554 int result = MapSystemError(os_error);
449 LogWrite(result, NULL, NULL); 555 LogWrite(result, NULL, NULL);
450 return result; 556 return result;
451 } 557 }
452 } 558 }
453 559
454 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); 560 core_->WatchForWrite();
561 core_->write_iobuffer_ = buf;
455 return ERR_IO_PENDING; 562 return ERR_IO_PENDING;
456 } 563 }
457 564
458 int UDPSocketWin::SetSocketOptions() { 565 int UDPSocketWin::SetSocketOptions() {
459 BOOL true_value = 1; 566 BOOL true_value = 1;
460 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { 567 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) {
461 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, 568 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR,
462 reinterpret_cast<const char*>(&true_value), 569 reinterpret_cast<const char*>(&true_value),
463 sizeof(true_value)); 570 sizeof(true_value));
464 if (rv < 0) 571 if (rv < 0)
(...skipping 25 matching lines...) Expand all
490 597
491 for (int i = 0; i < kBindRetries; ++i) { 598 for (int i = 0; i < kBindRetries; ++i) {
492 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); 599 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd)));
493 if (rv == OK || rv != ERR_ADDRESS_IN_USE) 600 if (rv == OK || rv != ERR_ADDRESS_IN_USE)
494 return rv; 601 return rv;
495 } 602 }
496 return DoBind(IPEndPoint(ip, 0)); 603 return DoBind(IPEndPoint(ip, 0));
497 } 604 }
498 605
499 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { 606 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const {
500 const struct sockaddr* addr = 607 SockaddrStorage& storage = core_->recv_addr_storage_;
501 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); 608 return address->FromSockAddr(storage.addr, storage.addr_len);
502 return address->FromSockAddr(addr, recv_addr_len_);
503 } 609 }
504 610
505 } // namespace net 611 } // namespace net
OLDNEW
« no previous file with comments | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698