| 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 |