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

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: 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
« net/udp/udp_socket_win.h ('K') | « 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 WSABUF read_buffer_;
56 WSABUF write_buffer_;
wtc 2012/09/12 01:40:29 It turns out these two buffers don't need to be me
wtc 2012/09/12 04:00:43 I have created a CL for TCPClientSocketWin: http:/
szym 2012/09/12 15:14:06 That snippet from MSDN was the reason why I decide
57 scoped_refptr<IOBuffer> read_iobuffer_;
58 scoped_refptr<IOBuffer> write_iobuffer_;
59
60 private:
61 friend class base::RefCounted<Core>;
62
63 class ReadDelegate : public base::win::ObjectWatcher::Delegate {
64 public:
65 explicit ReadDelegate(Core* core) : core_(core) {}
66 virtual ~ReadDelegate() {}
67
68 // base::ObjectWatcher::Delegate methods:
69 virtual void OnObjectSignaled(HANDLE object);
70
71 private:
72 Core* const core_;
73 };
74
75 class WriteDelegate : public base::win::ObjectWatcher::Delegate {
76 public:
77 explicit WriteDelegate(Core* core) : core_(core) {}
78 virtual ~WriteDelegate() {}
79
80 // base::ObjectWatcher::Delegate methods:
81 virtual void OnObjectSignaled(HANDLE object);
82
83 private:
84 Core* const core_;
85 };
86
87 ~Core();
88
89 // The socket that created this object.
90 UDPSocketWin* socket_;
91
92 // |reader_| handles the signals from |read_watcher_|.
93 ReadDelegate reader_;
94 // |writer_| handles the signals from |write_watcher_|.
95 WriteDelegate writer_;
96
97 // |read_watcher_| watches for events from Connect() and Read().
wtc 2012/09/12 01:40:29 Delete "Connect() and"?
szym 2012/09/12 15:14:06 Done.
98 base::win::ObjectWatcher read_watcher_;
99 // |write_watcher_| watches for events from Write();
100 base::win::ObjectWatcher write_watcher_;
101
102 DISALLOW_COPY_AND_ASSIGN(Core);
103 };
104
105 UDPSocketWin::Core::Core(UDPSocketWin* socket)
106 : socket_(socket),
107 ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)),
108 ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)) {
109 memset(&read_overlapped_, 0, sizeof(read_overlapped_));
110 memset(&write_overlapped_, 0, sizeof(write_overlapped_));
111
112 read_overlapped_.hEvent = WSACreateEvent();
113 write_overlapped_.hEvent = WSACreateEvent();
37 } 114 }
38 115
39 void UDPSocketWin::WriteDelegate::OnObjectSignaled(HANDLE object) { 116 UDPSocketWin::Core::~Core() {
40 DCHECK_EQ(object, socket_->write_overlapped_.hEvent); 117 // Make sure the message loop is not watching this object anymore.
41 socket_->DidCompleteWrite(); 118 read_watcher_.StopWatching();
119 write_watcher_.StopWatching();
120
121 WSACloseEvent(read_overlapped_.hEvent);
122 memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_));
123 WSACloseEvent(write_overlapped_.hEvent);
124 memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_));
42 } 125 }
43 126
127 void UDPSocketWin::Core::WatchForRead() {
128 // We grab an extra reference because there is an IO operation in progress.
129 // Balanced in ReadDelegate::OnObjectSignaled().
130 AddRef();
131 read_watcher_.StartWatching(read_overlapped_.hEvent, &reader_);
132 }
133
134 void UDPSocketWin::Core::WatchForWrite() {
135 // We grab an extra reference because there is an IO operation in progress.
136 // Balanced in WriteDelegate::OnObjectSignaled().
137 AddRef();
138 write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_);
139 }
140
141 void UDPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) {
142 DCHECK_EQ(object, core_->read_overlapped_.hEvent);
143 if (core_->socket_)
144 core_->socket_->DidCompleteRead();
145
146 core_->Release();
147 }
148
149 void UDPSocketWin::Core::WriteDelegate::OnObjectSignaled(HANDLE object) {
150 DCHECK_EQ(object, core_->write_overlapped_.hEvent);
151 if (core_->socket_)
152 core_->socket_->DidCompleteWrite();
153
154 core_->Release();
155 }
156
157 //-----------------------------------------------------------------------------
158
44 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, 159 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type,
45 const RandIntCallback& rand_int_cb, 160 const RandIntCallback& rand_int_cb,
46 net::NetLog* net_log, 161 net::NetLog* net_log,
47 const net::NetLog::Source& source) 162 const net::NetLog::Source& source)
48 : socket_(INVALID_SOCKET), 163 : socket_(INVALID_SOCKET),
49 socket_options_(0), 164 socket_options_(0),
50 bind_type_(bind_type), 165 bind_type_(bind_type),
51 rand_int_cb_(rand_int_cb), 166 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), 167 recv_from_address_(NULL),
55 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { 168 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) {
56 EnsureWinsockInit(); 169 EnsureWinsockInit();
57 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, 170 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE,
58 source.ToEventParametersCallback()); 171 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) 172 if (bind_type == DatagramSocket::RANDOM_BIND)
64 DCHECK(!rand_int_cb.is_null()); 173 DCHECK(!rand_int_cb.is_null());
65 } 174 }
66 175
67 UDPSocketWin::~UDPSocketWin() { 176 UDPSocketWin::~UDPSocketWin() {
68 Close(); 177 Close();
69 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); 178 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE);
70 } 179 }
71 180
72 void UDPSocketWin::Close() { 181 void UDPSocketWin::Close() {
73 DCHECK(CalledOnValidThread()); 182 DCHECK(CalledOnValidThread());
74 183
75 if (!is_connected()) 184 if (!is_connected())
76 return; 185 return;
77 186
78 // Zero out any pending read/write callback state. 187 // Zero out any pending read/write callback state.
79 read_callback_.Reset(); 188 read_callback_.Reset();
80 recv_from_address_ = NULL; 189 recv_from_address_ = NULL;
81 write_callback_.Reset(); 190 write_callback_.Reset();
82 191
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_); 192 closesocket(socket_);
92 socket_ = INVALID_SOCKET; 193 socket_ = INVALID_SOCKET;
194
195 if (core_.get())
wtc 2012/09/12 01:40:29 Is this null pointer check necessary? It is not in
szym 2012/09/12 02:23:45 It should, I added this in response to a failing t
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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 DCHECK(!write_callback_.is_null()); 401 DCHECK(!write_callback_.is_null());
299 402
300 // since Run may result in Write being called, clear write_callback_ up front. 403 // since Run may result in Write being called, clear write_callback_ up front.
301 CompletionCallback c = write_callback_; 404 CompletionCallback c = write_callback_;
302 write_callback_.Reset(); 405 write_callback_.Reset();
303 c.Run(rv); 406 c.Run(rv);
304 } 407 }
305 408
306 void UDPSocketWin::DidCompleteRead() { 409 void UDPSocketWin::DidCompleteRead() {
307 DWORD num_bytes, flags; 410 DWORD num_bytes, flags;
308 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, 411 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_,
309 &num_bytes, FALSE, &flags); 412 &num_bytes, FALSE, &flags);
310 WSAResetEvent(read_overlapped_.hEvent); 413 WSAResetEvent(core_->read_overlapped_.hEvent);
311 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); 414 int result = ok ? num_bytes : MapSystemError(WSAGetLastError());
312 // Convert address. 415 // Convert address.
313 if (recv_from_address_ && result >= 0) { 416 if (recv_from_address_ && result >= 0) {
314 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) 417 if (!ReceiveAddressToIPEndpoint(recv_from_address_))
315 result = ERR_FAILED; 418 result = ERR_FAILED;
316 } 419 }
317 LogRead(result, read_iobuffer_->data()); 420 LogRead(result, core_->read_iobuffer_->data());
318 read_iobuffer_ = NULL; 421 core_->read_iobuffer_ = NULL;
319 recv_from_address_ = NULL; 422 recv_from_address_ = NULL;
320 DoReadCallback(result); 423 DoReadCallback(result);
321 } 424 }
322 425
323 void UDPSocketWin::LogRead(int result, const char* bytes) const { 426 void UDPSocketWin::LogRead(int result, const char* bytes) const {
324 if (result < 0) { 427 if (result < 0) {
325 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); 428 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result);
326 return; 429 return;
327 } 430 }
328 431
329 if (net_log_.IsLoggingAllEvents()) { 432 if (net_log_.IsLoggingAllEvents()) {
330 // Get address for logging, if |address| is NULL. 433 // Get address for logging, if |address| is NULL.
331 IPEndPoint address; 434 IPEndPoint address;
332 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); 435 bool is_address_valid = ReceiveAddressToIPEndpoint(&address);
333 net_log_.AddEvent( 436 net_log_.AddEvent(
334 NetLog::TYPE_UDP_BYTES_RECEIVED, 437 NetLog::TYPE_UDP_BYTES_RECEIVED,
335 CreateNetLogUDPDataTranferCallback( 438 CreateNetLogUDPDataTranferCallback(
336 result, bytes, 439 result, bytes,
337 is_address_valid ? &address : NULL)); 440 is_address_valid ? &address : NULL));
338 } 441 }
339 442
340 base::StatsCounter read_bytes("udp.read_bytes"); 443 base::StatsCounter read_bytes("udp.read_bytes");
341 read_bytes.Add(result); 444 read_bytes.Add(result);
342 } 445 }
343 446
344 void UDPSocketWin::DidCompleteWrite() { 447 void UDPSocketWin::DidCompleteWrite() {
345 DWORD num_bytes, flags; 448 DWORD num_bytes, flags;
346 BOOL ok = WSAGetOverlappedResult(socket_, &write_overlapped_, 449 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_,
347 &num_bytes, FALSE, &flags); 450 &num_bytes, FALSE, &flags);
348 WSAResetEvent(write_overlapped_.hEvent); 451 WSAResetEvent(core_->write_overlapped_.hEvent);
349 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); 452 int result = ok ? num_bytes : MapSystemError(WSAGetLastError());
350 LogWrite(result, write_iobuffer_->data(), send_to_address_.get()); 453 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get());
351 454
352 send_to_address_.reset(); 455 send_to_address_.reset();
353 write_iobuffer_ = NULL; 456 core_->write_iobuffer_ = NULL;
354 DoWriteCallback(result); 457 DoWriteCallback(result);
355 } 458 }
356 459
357 void UDPSocketWin::LogWrite(int result, 460 void UDPSocketWin::LogWrite(int result,
358 const char* bytes, 461 const char* bytes,
359 const IPEndPoint* address) const { 462 const IPEndPoint* address) const {
360 if (result < 0) { 463 if (result < 0) {
361 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); 464 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result);
362 return; 465 return;
363 } 466 }
364 467
365 if (net_log_.IsLoggingAllEvents()) { 468 if (net_log_.IsLoggingAllEvents()) {
366 net_log_.AddEvent( 469 net_log_.AddEvent(
367 NetLog::TYPE_UDP_BYTES_SENT, 470 NetLog::TYPE_UDP_BYTES_SENT,
368 CreateNetLogUDPDataTranferCallback(result, bytes, address)); 471 CreateNetLogUDPDataTranferCallback(result, bytes, address));
369 } 472 }
370 473
371 base::StatsCounter write_bytes("udp.write_bytes"); 474 base::StatsCounter write_bytes("udp.write_bytes");
372 write_bytes.Add(result); 475 write_bytes.Add(result);
373 } 476 }
374 477
375 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, 478 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len,
376 IPEndPoint* address) { 479 IPEndPoint* address) {
wtc 2012/09/12 01:40:29 I suggest copying DCHECK(!core_->read_iobuffer_)
szym 2012/09/12 15:14:06 Done.
377 recv_addr_len_ = sizeof(recv_addr_storage_); 480 recv_addr_len_ = sizeof(recv_addr_storage_);
378 struct sockaddr* addr = 481 struct sockaddr* addr =
379 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); 482 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_);
380 483
381 WSABUF read_buffer; 484 if (!core_)
382 read_buffer.buf = buf->data(); 485 core_ = new Core(this);
wtc 2012/09/12 01:40:29 I think we can simply create Core in the UDPSocket
szym 2012/09/12 02:23:45 This will definitely be moved from here, either to
wtc 2012/09/12 04:00:43 I think TCPClientSocketWin creates Core lazily bec
szym 2012/09/12 15:14:06 It seems UDOSocketWin can be re-Connected or re-Bo
383 read_buffer.len = buf_len; 486 core_->read_iobuffer_ = buf;
wtc 2012/09/12 01:40:29 BUG: this can be a reference leak. You need to rel
szym 2012/09/12 15:14:06 Done.
487 core_->read_buffer_.buf = buf->data();
488 core_->read_buffer_.len = buf_len;
384 489
385 DWORD flags = 0; 490 DWORD flags = 0;
386 DWORD num; 491 DWORD num;
387 CHECK_NE(INVALID_SOCKET, socket_); 492 CHECK_NE(INVALID_SOCKET, socket_);
388 AssertEventNotSignaled(read_overlapped_.hEvent); 493 AssertEventNotSignaled(core_->read_overlapped_.hEvent);
389 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, addr, 494 int rv = WSARecvFrom(socket_, &core_->read_buffer_, 1, &num, &flags, addr,
390 &recv_addr_len_, &read_overlapped_, NULL); 495 &recv_addr_len_, &core_->read_overlapped_, NULL);
391 if (rv == 0) { 496 if (rv == 0) {
392 if (ResetEventIfSignaled(read_overlapped_.hEvent)) { 497 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) {
393 int result = num; 498 int result = num;
394 // Convert address. 499 // Convert address.
395 if (address && result >= 0) { 500 if (address && result >= 0) {
396 if (!ReceiveAddressToIPEndpoint(address)) 501 if (!ReceiveAddressToIPEndpoint(address))
397 result = ERR_FAILED; 502 result = ERR_FAILED;
398 } 503 }
399 LogRead(result, buf->data()); 504 LogRead(result, buf->data());
400 return result; 505 return result;
401 } 506 }
402 } else { 507 } else {
403 int os_error = WSAGetLastError(); 508 int os_error = WSAGetLastError();
404 if (os_error != WSA_IO_PENDING) { 509 if (os_error != WSA_IO_PENDING) {
405 int result = MapSystemError(os_error); 510 int result = MapSystemError(os_error);
406 LogRead(result, NULL); 511 LogRead(result, NULL);
407 return result; 512 return result;
408 } 513 }
409 } 514 }
410 read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_); 515 core_->WatchForRead();
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,
wtc 2012/09/12 01:40:29 IMPORTANT: All of my comments for UDPSocketWin::In
szym 2012/09/12 15:14:06 Done.
415 const IPEndPoint* address) { 520 const IPEndPoint* address) {
416 SockaddrStorage storage; 521 SockaddrStorage storage;
417 struct sockaddr* addr = storage.addr; 522 struct sockaddr* addr = storage.addr;
418 // Convert address. 523 // Convert address.
419 if (!address) { 524 if (!address) {
420 addr = NULL; 525 addr = NULL;
421 storage.addr_len = 0; 526 storage.addr_len = 0;
422 } else { 527 } else {
423 if (!address->ToSockAddr(addr, &storage.addr_len)) { 528 if (!address->ToSockAddr(addr, &storage.addr_len)) {
424 int result = ERR_FAILED; 529 int result = ERR_FAILED;
425 LogWrite(result, NULL, NULL); 530 LogWrite(result, NULL, NULL);
426 return result; 531 return result;
427 } 532 }
428 } 533 }
429 534
430 WSABUF write_buffer; 535 if (!core_.get())
431 write_buffer.buf = buf->data(); 536 core_ = new Core(this);
432 write_buffer.len = buf_len; 537 core_->write_iobuffer_ = buf;
538 core_->write_buffer_.buf = buf->data();
539 core_->write_buffer_.len = buf_len;
433 540
434 DWORD flags = 0; 541 DWORD flags = 0;
435 DWORD num; 542 DWORD num;
436 AssertEventNotSignaled(write_overlapped_.hEvent); 543 AssertEventNotSignaled(core_->write_overlapped_.hEvent);
437 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, 544 int rv = WSASendTo(socket_, &core_->write_buffer_, 1, &num, flags,
438 addr, storage.addr_len, &write_overlapped_, NULL); 545 addr, storage.addr_len, &core_->write_overlapped_, NULL);
439 if (rv == 0) { 546 if (rv == 0) {
440 if (ResetEventIfSignaled(write_overlapped_.hEvent)) { 547 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) {
441 int result = num; 548 int result = num;
442 LogWrite(result, buf->data(), address); 549 LogWrite(result, buf->data(), address);
443 return result; 550 return result;
444 } 551 }
445 } else { 552 } else {
446 int os_error = WSAGetLastError(); 553 int os_error = WSAGetLastError();
447 if (os_error != WSA_IO_PENDING) { 554 if (os_error != WSA_IO_PENDING) {
448 int result = MapSystemError(os_error); 555 int result = MapSystemError(os_error);
449 LogWrite(result, NULL, NULL); 556 LogWrite(result, NULL, NULL);
450 return result; 557 return result;
451 } 558 }
452 } 559 }
453 560
454 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); 561 core_->WatchForWrite();
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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 const struct sockaddr* addr =
501 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); 608 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_);
502 return address->FromSockAddr(addr, recv_addr_len_); 609 return address->FromSockAddr(addr, recv_addr_len_);
503 } 610 }
504 611
505 } // namespace net 612 } // namespace net
OLDNEW
« net/udp/udp_socket_win.h ('K') | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698