OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/base/tcp_client_socket_win.h" | 5 #include "net/base/tcp_client_socket_win.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/memory_debug.h" | 9 #include "base/memory_debug.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 WSACloseEvent(read_overlapped_.hEvent); | 166 WSACloseEvent(read_overlapped_.hEvent); |
167 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 167 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
168 WSACloseEvent(write_overlapped_.hEvent); | 168 WSACloseEvent(write_overlapped_.hEvent); |
169 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | 169 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); |
170 | 170 |
171 // Reset for next time. | 171 // Reset for next time. |
172 current_ai_ = addresses_.head(); | 172 current_ai_ = addresses_.head(); |
173 | 173 |
174 waiting_read_ = false; | 174 waiting_read_ = false; |
175 waiting_write_ = false; | 175 waiting_write_ = false; |
| 176 read_iobuffer_ = NULL; |
| 177 write_iobuffer_ = NULL; |
176 waiting_connect_ = false; | 178 waiting_connect_ = false; |
177 } | 179 } |
178 | 180 |
179 bool TCPClientSocketWin::IsConnected() const { | 181 bool TCPClientSocketWin::IsConnected() const { |
180 if (socket_ == INVALID_SOCKET || waiting_connect_) | 182 if (socket_ == INVALID_SOCKET || waiting_connect_) |
181 return false; | 183 return false; |
182 | 184 |
183 // Check if connection is alive. | 185 // Check if connection is alive. |
184 char c; | 186 char c; |
185 int rv = recv(socket_, &c, 1, MSG_PEEK); | 187 int rv = recv(socket_, &c, 1, MSG_PEEK); |
(...skipping 14 matching lines...) Expand all Loading... |
200 char c; | 202 char c; |
201 int rv = recv(socket_, &c, 1, MSG_PEEK); | 203 int rv = recv(socket_, &c, 1, MSG_PEEK); |
202 if (rv >= 0) | 204 if (rv >= 0) |
203 return false; | 205 return false; |
204 if (WSAGetLastError() != WSAEWOULDBLOCK) | 206 if (WSAGetLastError() != WSAEWOULDBLOCK) |
205 return false; | 207 return false; |
206 | 208 |
207 return true; | 209 return true; |
208 } | 210 } |
209 | 211 |
210 int TCPClientSocketWin::Read(char* buf, | 212 int TCPClientSocketWin::Read(IOBuffer* buf, |
211 int buf_len, | 213 int buf_len, |
212 CompletionCallback* callback) { | 214 CompletionCallback* callback) { |
213 DCHECK_NE(socket_, INVALID_SOCKET); | 215 DCHECK_NE(socket_, INVALID_SOCKET); |
214 DCHECK(!waiting_read_); | 216 DCHECK(!waiting_read_); |
215 DCHECK(!read_callback_); | 217 DCHECK(!read_callback_); |
| 218 DCHECK(!read_iobuffer_); |
216 | 219 |
217 read_buffer_.len = buf_len; | 220 read_buffer_.len = buf_len; |
218 read_buffer_.buf = buf; | 221 read_buffer_.buf = buf->data(); |
219 | 222 |
220 TRACE_EVENT_BEGIN("socket.read", this, ""); | 223 TRACE_EVENT_BEGIN("socket.read", this, ""); |
221 // TODO(wtc): Remove the CHECK after enough testing. | 224 // TODO(wtc): Remove the CHECK after enough testing. |
222 CHECK(WaitForSingleObject(read_overlapped_.hEvent, 0) == WAIT_TIMEOUT); | 225 CHECK(WaitForSingleObject(read_overlapped_.hEvent, 0) == WAIT_TIMEOUT); |
223 DWORD num, flags = 0; | 226 DWORD num, flags = 0; |
224 int rv = WSARecv( | 227 int rv = WSARecv( |
225 socket_, &read_buffer_, 1, &num, &flags, &read_overlapped_, NULL); | 228 socket_, &read_buffer_, 1, &num, &flags, &read_overlapped_, NULL); |
226 if (rv == 0) { | 229 if (rv == 0) { |
227 WaitForAndResetEvent(read_overlapped_.hEvent); | 230 WaitForAndResetEvent(read_overlapped_.hEvent); |
228 TRACE_EVENT_END("socket.read", this, StringPrintf("%d bytes", num)); | 231 TRACE_EVENT_END("socket.read", this, StringPrintf("%d bytes", num)); |
229 | 232 |
230 // Because of how WSARecv fills memory when used asynchronously, Purify | 233 // Because of how WSARecv fills memory when used asynchronously, Purify |
231 // isn't able to detect that it's been initialized, so it scans for 0xcd | 234 // isn't able to detect that it's been initialized, so it scans for 0xcd |
232 // in the buffer and reports UMRs (uninitialized memory reads) for those | 235 // in the buffer and reports UMRs (uninitialized memory reads) for those |
233 // individual bytes. We override that in PURIFY builds to avoid the false | 236 // individual bytes. We override that in PURIFY builds to avoid the false |
234 // error reports. | 237 // error reports. |
235 // See bug 5297. | 238 // See bug 5297. |
236 base::MemoryDebug::MarkAsInitialized(read_buffer_.buf, num); | 239 base::MemoryDebug::MarkAsInitialized(read_buffer_.buf, num); |
237 return static_cast<int>(num); | 240 return static_cast<int>(num); |
238 } | 241 } |
239 int err = WSAGetLastError(); | 242 int err = WSAGetLastError(); |
240 if (err == WSA_IO_PENDING) { | 243 if (err == WSA_IO_PENDING) { |
241 read_watcher_.StartWatching(read_overlapped_.hEvent, &reader_); | 244 read_watcher_.StartWatching(read_overlapped_.hEvent, &reader_); |
242 waiting_read_ = true; | 245 waiting_read_ = true; |
243 read_callback_ = callback; | 246 read_callback_ = callback; |
| 247 read_iobuffer_ = buf; |
244 return ERR_IO_PENDING; | 248 return ERR_IO_PENDING; |
245 } | 249 } |
246 return MapWinsockError(err); | 250 return MapWinsockError(err); |
247 } | 251 } |
248 | 252 |
249 int TCPClientSocketWin::Write(const char* buf, | 253 int TCPClientSocketWin::Write(IOBuffer* buf, |
250 int buf_len, | 254 int buf_len, |
251 CompletionCallback* callback) { | 255 CompletionCallback* callback) { |
252 DCHECK_NE(socket_, INVALID_SOCKET); | 256 DCHECK_NE(socket_, INVALID_SOCKET); |
253 DCHECK(!waiting_write_); | 257 DCHECK(!waiting_write_); |
254 DCHECK(!write_callback_); | 258 DCHECK(!write_callback_); |
255 DCHECK_GT(buf_len, 0); | 259 DCHECK_GT(buf_len, 0); |
| 260 DCHECK(!write_iobuffer_); |
256 | 261 |
257 write_buffer_.len = buf_len; | 262 write_buffer_.len = buf_len; |
258 write_buffer_.buf = const_cast<char*>(buf); | 263 write_buffer_.buf = buf->data(); |
259 | 264 |
260 TRACE_EVENT_BEGIN("socket.write", this, ""); | 265 TRACE_EVENT_BEGIN("socket.write", this, ""); |
261 // TODO(wtc): Remove the CHECK after enough testing. | 266 // TODO(wtc): Remove the CHECK after enough testing. |
262 CHECK(WaitForSingleObject(write_overlapped_.hEvent, 0) == WAIT_TIMEOUT); | 267 CHECK(WaitForSingleObject(write_overlapped_.hEvent, 0) == WAIT_TIMEOUT); |
263 DWORD num; | 268 DWORD num; |
264 int rv = | 269 int rv = |
265 WSASend(socket_, &write_buffer_, 1, &num, 0, &write_overlapped_, NULL); | 270 WSASend(socket_, &write_buffer_, 1, &num, 0, &write_overlapped_, NULL); |
266 if (rv == 0) { | 271 if (rv == 0) { |
267 WaitForAndResetEvent(write_overlapped_.hEvent); | 272 WaitForAndResetEvent(write_overlapped_.hEvent); |
268 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", num)); | 273 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", num)); |
269 return static_cast<int>(num); | 274 return static_cast<int>(num); |
270 } | 275 } |
271 int err = WSAGetLastError(); | 276 int err = WSAGetLastError(); |
272 if (err == WSA_IO_PENDING) { | 277 if (err == WSA_IO_PENDING) { |
273 write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_); | 278 write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_); |
274 waiting_write_ = true; | 279 waiting_write_ = true; |
275 write_callback_ = callback; | 280 write_callback_ = callback; |
| 281 write_iobuffer_ = buf; |
276 return ERR_IO_PENDING; | 282 return ERR_IO_PENDING; |
277 } | 283 } |
278 return MapWinsockError(err); | 284 return MapWinsockError(err); |
279 } | 285 } |
280 | 286 |
281 int TCPClientSocketWin::CreateSocket(const struct addrinfo* ai) { | 287 int TCPClientSocketWin::CreateSocket(const struct addrinfo* ai) { |
282 socket_ = WSASocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, NULL, 0, | 288 socket_ = WSASocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, NULL, 0, |
283 WSA_FLAG_OVERLAPPED); | 289 WSA_FLAG_OVERLAPPED); |
284 if (socket_ == INVALID_SOCKET) { | 290 if (socket_ == INVALID_SOCKET) { |
285 DWORD err = WSAGetLastError(); | 291 DWORD err = WSAGetLastError(); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 if (result != ERR_IO_PENDING) | 404 if (result != ERR_IO_PENDING) |
399 DoReadCallback(result); | 405 DoReadCallback(result); |
400 } | 406 } |
401 | 407 |
402 void TCPClientSocketWin::ReadDelegate::OnObjectSignaled(HANDLE object) { | 408 void TCPClientSocketWin::ReadDelegate::OnObjectSignaled(HANDLE object) { |
403 DCHECK_EQ(object, tcp_socket_->read_overlapped_.hEvent); | 409 DCHECK_EQ(object, tcp_socket_->read_overlapped_.hEvent); |
404 | 410 |
405 if (tcp_socket_->waiting_connect_) { | 411 if (tcp_socket_->waiting_connect_) { |
406 tcp_socket_->DidCompleteConnect(); | 412 tcp_socket_->DidCompleteConnect(); |
407 } else { | 413 } else { |
| 414 DCHECK(tcp_socket_->waiting_read_); |
408 DWORD num_bytes, flags; | 415 DWORD num_bytes, flags; |
409 BOOL ok = WSAGetOverlappedResult( | 416 BOOL ok = WSAGetOverlappedResult( |
410 tcp_socket_->socket_, &tcp_socket_->read_overlapped_, &num_bytes, | 417 tcp_socket_->socket_, &tcp_socket_->read_overlapped_, &num_bytes, |
411 FALSE, &flags); | 418 FALSE, &flags); |
412 WSAResetEvent(object); | 419 WSAResetEvent(object); |
413 TRACE_EVENT_END("socket.read", tcp_socket_, | 420 TRACE_EVENT_END("socket.read", tcp_socket_, |
414 StringPrintf("%d bytes", num_bytes)); | 421 StringPrintf("%d bytes", num_bytes)); |
415 tcp_socket_->waiting_read_ = false; | 422 tcp_socket_->waiting_read_ = false; |
| 423 tcp_socket_->read_iobuffer_ = NULL; |
416 tcp_socket_->DoReadCallback( | 424 tcp_socket_->DoReadCallback( |
417 ok ? num_bytes : MapWinsockError(WSAGetLastError())); | 425 ok ? num_bytes : MapWinsockError(WSAGetLastError())); |
418 } | 426 } |
419 } | 427 } |
420 | 428 |
421 void TCPClientSocketWin::WriteDelegate::OnObjectSignaled(HANDLE object) { | 429 void TCPClientSocketWin::WriteDelegate::OnObjectSignaled(HANDLE object) { |
422 DCHECK_EQ(object, tcp_socket_->write_overlapped_.hEvent); | 430 DCHECK_EQ(object, tcp_socket_->write_overlapped_.hEvent); |
| 431 DCHECK(tcp_socket_->waiting_write_); |
423 | 432 |
424 DWORD num_bytes, flags; | 433 DWORD num_bytes, flags; |
425 BOOL ok = WSAGetOverlappedResult( | 434 BOOL ok = WSAGetOverlappedResult( |
426 tcp_socket_->socket_, &tcp_socket_->write_overlapped_, &num_bytes, | 435 tcp_socket_->socket_, &tcp_socket_->write_overlapped_, &num_bytes, |
427 FALSE, &flags); | 436 FALSE, &flags); |
428 WSAResetEvent(object); | 437 WSAResetEvent(object); |
429 TRACE_EVENT_END("socket.write", tcp_socket_, | 438 TRACE_EVENT_END("socket.write", tcp_socket_, |
430 StringPrintf("%d bytes", num_bytes)); | 439 StringPrintf("%d bytes", num_bytes)); |
431 tcp_socket_->waiting_write_ = false; | 440 tcp_socket_->waiting_write_ = false; |
| 441 tcp_socket_->write_iobuffer_ = NULL; |
432 tcp_socket_->DoWriteCallback( | 442 tcp_socket_->DoWriteCallback( |
433 ok ? num_bytes : MapWinsockError(WSAGetLastError())); | 443 ok ? num_bytes : MapWinsockError(WSAGetLastError())); |
434 } | 444 } |
435 | 445 |
436 } // namespace net | 446 } // namespace net |
OLD | NEW |