OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/eintr_wrapper.h" | 9 #include "base/eintr_wrapper.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, | 44 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, |
45 const RandIntCallback& rand_int_cb, | 45 const RandIntCallback& rand_int_cb, |
46 net::NetLog* net_log, | 46 net::NetLog* net_log, |
47 const net::NetLog::Source& source) | 47 const net::NetLog::Source& source) |
48 : socket_(INVALID_SOCKET), | 48 : socket_(INVALID_SOCKET), |
49 bind_type_(bind_type), | 49 bind_type_(bind_type), |
50 rand_int_cb_(rand_int_cb), | 50 rand_int_cb_(rand_int_cb), |
51 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), | 51 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), |
52 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), | 52 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), |
53 recv_from_address_(NULL), | 53 recv_from_address_(NULL), |
54 read_callback_(NULL), | 54 old_read_callback_(NULL), |
55 write_callback_(NULL), | 55 write_callback_(NULL), |
56 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { | 56 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
57 EnsureWinsockInit(); | 57 EnsureWinsockInit(); |
58 scoped_refptr<NetLog::EventParameters> params; | 58 scoped_refptr<NetLog::EventParameters> params; |
59 if (source.is_valid()) | 59 if (source.is_valid()) |
60 params = new NetLogSourceParameter("source_dependency", source); | 60 params = new NetLogSourceParameter("source_dependency", source); |
61 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 61 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
62 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 62 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
63 read_overlapped_.hEvent = WSACreateEvent(); | 63 read_overlapped_.hEvent = WSACreateEvent(); |
64 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | 64 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); |
65 write_overlapped_.hEvent = WSACreateEvent(); | 65 write_overlapped_.hEvent = WSACreateEvent(); |
66 if (bind_type == DatagramSocket::RANDOM_BIND) | 66 if (bind_type == DatagramSocket::RANDOM_BIND) |
67 DCHECK(!rand_int_cb.is_null()); | 67 DCHECK(!rand_int_cb.is_null()); |
68 } | 68 } |
69 | 69 |
70 UDPSocketWin::~UDPSocketWin() { | 70 UDPSocketWin::~UDPSocketWin() { |
71 Close(); | 71 Close(); |
72 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); | 72 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); |
73 } | 73 } |
74 | 74 |
75 void UDPSocketWin::Close() { | 75 void UDPSocketWin::Close() { |
76 DCHECK(CalledOnValidThread()); | 76 DCHECK(CalledOnValidThread()); |
77 | 77 |
78 if (!is_connected()) | 78 if (!is_connected()) |
79 return; | 79 return; |
80 | 80 |
81 // Zero out any pending read/write callback state. | 81 // Zero out any pending read/write callback state. |
82 read_callback_ = NULL; | 82 old_read_callback_ = NULL; |
| 83 read_callback_.Reset(); |
83 recv_from_address_ = NULL; | 84 recv_from_address_ = NULL; |
84 write_callback_ = NULL; | 85 write_callback_ = NULL; |
85 | 86 |
86 read_watcher_.StopWatching(); | 87 read_watcher_.StopWatching(); |
87 write_watcher_.StopWatching(); | 88 write_watcher_.StopWatching(); |
88 | 89 |
89 closesocket(socket_); | 90 closesocket(socket_); |
90 socket_ = INVALID_SOCKET; | 91 socket_ = INVALID_SOCKET; |
91 } | 92 } |
92 | 93 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 | 133 |
133 *address = *local_address_; | 134 *address = *local_address_; |
134 return OK; | 135 return OK; |
135 } | 136 } |
136 | 137 |
137 int UDPSocketWin::Read(IOBuffer* buf, | 138 int UDPSocketWin::Read(IOBuffer* buf, |
138 int buf_len, | 139 int buf_len, |
139 OldCompletionCallback* callback) { | 140 OldCompletionCallback* callback) { |
140 return RecvFrom(buf, buf_len, NULL, callback); | 141 return RecvFrom(buf, buf_len, NULL, callback); |
141 } | 142 } |
| 143 int UDPSocketWin::Read(IOBuffer* buf, |
| 144 int buf_len, |
| 145 const CompletionCallback& callback) { |
| 146 return RecvFrom(buf, buf_len, NULL, callback); |
| 147 } |
142 | 148 |
143 int UDPSocketWin::RecvFrom(IOBuffer* buf, | 149 int UDPSocketWin::RecvFrom(IOBuffer* buf, |
144 int buf_len, | 150 int buf_len, |
145 IPEndPoint* address, | 151 IPEndPoint* address, |
146 OldCompletionCallback* callback) { | 152 OldCompletionCallback* callback) { |
147 DCHECK(CalledOnValidThread()); | 153 DCHECK(CalledOnValidThread()); |
148 DCHECK_NE(INVALID_SOCKET, socket_); | 154 DCHECK_NE(INVALID_SOCKET, socket_); |
149 DCHECK(!read_callback_); | 155 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
150 DCHECK(!recv_from_address_); | 156 DCHECK(!recv_from_address_); |
151 DCHECK(callback); // Synchronous operation not supported. | 157 DCHECK(callback); // Synchronous operation not supported. |
152 DCHECK_GT(buf_len, 0); | 158 DCHECK_GT(buf_len, 0); |
153 | 159 |
154 int nread = InternalRecvFrom(buf, buf_len, address); | 160 int nread = InternalRecvFrom(buf, buf_len, address); |
155 if (nread != ERR_IO_PENDING) | 161 if (nread != ERR_IO_PENDING) |
156 return nread; | 162 return nread; |
157 | 163 |
158 read_iobuffer_ = buf; | 164 read_iobuffer_ = buf; |
| 165 old_read_callback_ = callback; |
| 166 recv_from_address_ = address; |
| 167 return ERR_IO_PENDING; |
| 168 } |
| 169 int UDPSocketWin::RecvFrom(IOBuffer* buf, |
| 170 int buf_len, |
| 171 IPEndPoint* address, |
| 172 const CompletionCallback& callback) { |
| 173 DCHECK(CalledOnValidThread()); |
| 174 DCHECK_NE(INVALID_SOCKET, socket_); |
| 175 DCHECK(!old_read_callback_ && read_callback_.is_null()); |
| 176 DCHECK(!recv_from_address_); |
| 177 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
| 178 DCHECK_GT(buf_len, 0); |
| 179 |
| 180 int nread = InternalRecvFrom(buf, buf_len, address); |
| 181 if (nread != ERR_IO_PENDING) |
| 182 return nread; |
| 183 |
| 184 read_iobuffer_ = buf; |
159 read_callback_ = callback; | 185 read_callback_ = callback; |
160 recv_from_address_ = address; | 186 recv_from_address_ = address; |
161 return ERR_IO_PENDING; | 187 return ERR_IO_PENDING; |
162 } | 188 } |
163 | 189 |
164 int UDPSocketWin::Write(IOBuffer* buf, | 190 int UDPSocketWin::Write(IOBuffer* buf, |
165 int buf_len, | 191 int buf_len, |
166 OldCompletionCallback* callback) { | 192 OldCompletionCallback* callback) { |
167 return SendToOrWrite(buf, buf_len, NULL, callback); | 193 return SendToOrWrite(buf, buf_len, NULL, callback); |
168 } | 194 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 bool UDPSocketWin::SetSendBufferSize(int32 size) { | 291 bool UDPSocketWin::SetSendBufferSize(int32 size) { |
266 DCHECK(CalledOnValidThread()); | 292 DCHECK(CalledOnValidThread()); |
267 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 293 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, |
268 reinterpret_cast<const char*>(&size), sizeof(size)); | 294 reinterpret_cast<const char*>(&size), sizeof(size)); |
269 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; | 295 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; |
270 return rv == 0; | 296 return rv == 0; |
271 } | 297 } |
272 | 298 |
273 void UDPSocketWin::DoReadCallback(int rv) { | 299 void UDPSocketWin::DoReadCallback(int rv) { |
274 DCHECK_NE(rv, ERR_IO_PENDING); | 300 DCHECK_NE(rv, ERR_IO_PENDING); |
275 DCHECK(read_callback_); | 301 DCHECK(old_read_callback_ || !read_callback_.is_null()); |
276 | 302 |
277 // since Run may result in Read being called, clear read_callback_ up front. | 303 // since Run may result in Read being called, clear read_callback_ up front. |
278 OldCompletionCallback* c = read_callback_; | 304 if (old_read_callback_) { |
279 read_callback_ = NULL; | 305 OldCompletionCallback* c = old_read_callback_; |
280 c->Run(rv); | 306 old_read_callback_ = NULL; |
| 307 c->Run(rv); |
| 308 } else { |
| 309 CompletionCallback c = read_callback_; |
| 310 read_callback_.Reset(); |
| 311 c.Run(rv); |
| 312 } |
281 } | 313 } |
282 | 314 |
283 void UDPSocketWin::DoWriteCallback(int rv) { | 315 void UDPSocketWin::DoWriteCallback(int rv) { |
284 DCHECK_NE(rv, ERR_IO_PENDING); | 316 DCHECK_NE(rv, ERR_IO_PENDING); |
285 DCHECK(write_callback_); | 317 DCHECK(write_callback_); |
286 | 318 |
287 // since Run may result in Write being called, clear write_callback_ up front. | 319 // since Run may result in Write being called, clear write_callback_ up front. |
288 OldCompletionCallback* c = write_callback_; | 320 OldCompletionCallback* c = write_callback_; |
289 write_callback_ = NULL; | 321 write_callback_ = NULL; |
290 c->Run(rv); | 322 c->Run(rv); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 return DoBind(IPEndPoint(ip, 0)); | 503 return DoBind(IPEndPoint(ip, 0)); |
472 } | 504 } |
473 | 505 |
474 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { | 506 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { |
475 const struct sockaddr* addr = | 507 const struct sockaddr* addr = |
476 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); | 508 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); |
477 return address->FromSockAddr(addr, recv_addr_len_); | 509 return address->FromSockAddr(addr, recv_addr_len_); |
478 } | 510 } |
479 | 511 |
480 } // namespace net | 512 } // namespace net |
OLD | NEW |