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

Side by Side Diff: net/base/tcp_client_socket_win.cc

Issue 19515: In rare cases (when running inside QEMU), the event... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 10 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 | Annotate | Revision Log
« net/base/tcp_client_socket.h ('K') | « net/base/tcp_client_socket.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) 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.h" 5 #include "net/base/tcp_client_socket.h"
6 6
7 #include "base/memory_debug.h" 7 #include "base/memory_debug.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "base/trace_event.h" 9 #include "base/trace_event.h"
10 #include "net/base/net_errors.h" 10 #include "net/base/net_errors.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 return rv; 81 return rv;
82 82
83 // WSACreateEvent creates a manual-reset event object. 83 // WSACreateEvent creates a manual-reset event object.
84 overlapped_.hEvent = WSACreateEvent(); 84 overlapped_.hEvent = WSACreateEvent();
85 // WSAEventSelect sets the socket to non-blocking mode as a side effect. 85 // WSAEventSelect sets the socket to non-blocking mode as a side effect.
86 // Our connect() and recv() calls require that the socket be non-blocking. 86 // Our connect() and recv() calls require that the socket be non-blocking.
87 WSAEventSelect(socket_, overlapped_.hEvent, FD_CONNECT); 87 WSAEventSelect(socket_, overlapped_.hEvent, FD_CONNECT);
88 88
89 if (!connect(socket_, ai->ai_addr, static_cast<int>(ai->ai_addrlen))) { 89 if (!connect(socket_, ai->ai_addr, static_cast<int>(ai->ai_addrlen))) {
90 // Connected without waiting! 90 // Connected without waiting!
91 CHECK(WaitForSingleObject(overlapped_.hEvent, 0) == WAIT_OBJECT_0); 91 WaitForAndResetEvent();
92 BOOL ok = WSAResetEvent(overlapped_.hEvent);
93 CHECK(ok);
94 TRACE_EVENT_END("socket.connect", this, ""); 92 TRACE_EVENT_END("socket.connect", this, "");
95 return OK; 93 return OK;
96 } 94 }
97 95
98 DWORD err = WSAGetLastError(); 96 DWORD err = WSAGetLastError();
99 if (err != WSAEWOULDBLOCK) { 97 if (err != WSAEWOULDBLOCK) {
100 LOG(ERROR) << "connect failed: " << err; 98 LOG(ERROR) << "connect failed: " << err;
101 return MapWinsockError(err); 99 return MapWinsockError(err);
102 } 100 }
103 101
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 int buf_len, 161 int buf_len,
164 CompletionCallback* callback) { 162 CompletionCallback* callback) {
165 DCHECK(socket_ != INVALID_SOCKET); 163 DCHECK(socket_ != INVALID_SOCKET);
166 DCHECK(wait_state_ == NOT_WAITING); 164 DCHECK(wait_state_ == NOT_WAITING);
167 DCHECK(!callback_); 165 DCHECK(!callback_);
168 166
169 buffer_.len = buf_len; 167 buffer_.len = buf_len;
170 buffer_.buf = buf; 168 buffer_.buf = buf;
171 169
172 TRACE_EVENT_BEGIN("socket.read", this, ""); 170 TRACE_EVENT_BEGIN("socket.read", this, "");
173 // TODO(wtc): Remove the CHECKs after enough testing. 171 // TODO(wtc): Remove the CHECK after enough testing.
174 CHECK(WaitForSingleObject(overlapped_.hEvent, 0) == WAIT_TIMEOUT); 172 CHECK(WaitForSingleObject(overlapped_.hEvent, 0) == WAIT_TIMEOUT);
175 DWORD num, flags = 0; 173 DWORD num, flags = 0;
176 int rv = WSARecv(socket_, &buffer_, 1, &num, &flags, &overlapped_, NULL); 174 int rv = WSARecv(socket_, &buffer_, 1, &num, &flags, &overlapped_, NULL);
177 if (rv == 0) { 175 if (rv == 0) {
178 CHECK(WaitForSingleObject(overlapped_.hEvent, 0) == WAIT_OBJECT_0); 176 WaitForAndResetEvent();
179 BOOL ok = WSAResetEvent(overlapped_.hEvent);
180 CHECK(ok);
181 TRACE_EVENT_END("socket.read", this, StringPrintf("%d bytes", num)); 177 TRACE_EVENT_END("socket.read", this, StringPrintf("%d bytes", num));
182 178
183 // Because of how WSARecv fills memory when used asynchronously, Purify 179 // Because of how WSARecv fills memory when used asynchronously, Purify
184 // isn't able to detect that it's been initialized, so it scans for 0xcd 180 // isn't able to detect that it's been initialized, so it scans for 0xcd
185 // in the buffer and reports UMRs (uninitialized memory reads) for those 181 // in the buffer and reports UMRs (uninitialized memory reads) for those
186 // individual bytes. We override that in PURIFY builds to avoid the false 182 // individual bytes. We override that in PURIFY builds to avoid the false
187 // error reports. 183 // error reports.
188 // See bug 5297. 184 // See bug 5297.
189 base::MemoryDebug::MarkAsInitialized(buffer_.buf, num); 185 base::MemoryDebug::MarkAsInitialized(buffer_.buf, num);
190 return static_cast<int>(num); 186 return static_cast<int>(num);
191 } 187 }
192 int err = WSAGetLastError(); 188 int err = WSAGetLastError();
193 if (err == WSA_IO_PENDING) { 189 if (err == WSA_IO_PENDING) {
194 watcher_.StartWatching(overlapped_.hEvent, this); 190 watcher_.StartWatching(overlapped_.hEvent, this);
195 wait_state_ = WAITING_READ; 191 wait_state_ = WAITING_READ;
196 callback_ = callback; 192 callback_ = callback;
197 return ERR_IO_PENDING; 193 return ERR_IO_PENDING;
198 } 194 }
199 return MapWinsockError(err); 195 return MapWinsockError(err);
200 } 196 }
201 197
202 // TODO(wtc): This temporary function is intended to determine the return
203 // value and error code of the WaitForSingleObject call in
204 // TCPClientSocket::Write if it doesn't return the expected WAIT_OBJECT_0.
205 // See http://crbug.com/6500.
206 static void CrashBug6500(DWORD wait_rv, DWORD wait_error) {
207 // wait_error is meaningful only if wait_rv is WAIT_FAILED.
208 CHECK(false) << wait_rv << wait_error;
209 }
210
211 int TCPClientSocket::Write(const char* buf, 198 int TCPClientSocket::Write(const char* buf,
212 int buf_len, 199 int buf_len,
213 CompletionCallback* callback) { 200 CompletionCallback* callback) {
214 DCHECK(socket_ != INVALID_SOCKET); 201 DCHECK(socket_ != INVALID_SOCKET);
215 DCHECK(wait_state_ == NOT_WAITING); 202 DCHECK(wait_state_ == NOT_WAITING);
216 DCHECK(!callback_); 203 DCHECK(!callback_);
217 204
218 buffer_.len = buf_len; 205 buffer_.len = buf_len;
219 buffer_.buf = const_cast<char*>(buf); 206 buffer_.buf = const_cast<char*>(buf);
220 207
221 TRACE_EVENT_BEGIN("socket.write", this, ""); 208 TRACE_EVENT_BEGIN("socket.write", this, "");
222 // TODO(wtc): Remove the CHECKs after enough testing. 209 // TODO(wtc): Remove the CHECK after enough testing.
223 CHECK(WaitForSingleObject(overlapped_.hEvent, 0) == WAIT_TIMEOUT); 210 CHECK(WaitForSingleObject(overlapped_.hEvent, 0) == WAIT_TIMEOUT);
224 DWORD num; 211 DWORD num;
225 int rv = WSASend(socket_, &buffer_, 1, &num, 0, &overlapped_, NULL); 212 int rv = WSASend(socket_, &buffer_, 1, &num, 0, &overlapped_, NULL);
226 if (rv == 0) { 213 if (rv == 0) {
227 DWORD wait_rv = WaitForSingleObject(overlapped_.hEvent, 0); 214 WaitForAndResetEvent();
228 if (wait_rv != WAIT_OBJECT_0) {
229 DWORD wait_error = GetLastError();
230 CrashBug6500(wait_rv, wait_error);
231 }
232 BOOL ok = WSAResetEvent(overlapped_.hEvent);
233 CHECK(ok);
234 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", num)); 215 TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", num));
235 return static_cast<int>(num); 216 return static_cast<int>(num);
236 } 217 }
237 int err = WSAGetLastError(); 218 int err = WSAGetLastError();
238 if (err == WSA_IO_PENDING) { 219 if (err == WSA_IO_PENDING) {
239 watcher_.StartWatching(overlapped_.hEvent, this); 220 watcher_.StartWatching(overlapped_.hEvent, this);
240 wait_state_ = WAITING_WRITE; 221 wait_state_ = WAITING_WRITE;
241 callback_ = callback; 222 callback_ = callback;
242 return ERR_IO_PENDING; 223 return ERR_IO_PENDING;
243 } 224 }
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 case WAITING_READ: 353 case WAITING_READ:
373 case WAITING_WRITE: 354 case WAITING_WRITE:
374 DidCompleteIO(); 355 DidCompleteIO();
375 break; 356 break;
376 default: 357 default:
377 NOTREACHED(); 358 NOTREACHED();
378 break; 359 break;
379 } 360 }
380 } 361 }
381 362
363 void TCPClientSocket::WaitForAndResetEvent() {
364 // TODO(wtc): Remove the CHECKs after enough testing.
365 DWORD wait_rv = WaitForSingleObject(overlapped_.hEvent, INFINITE);
366 CHECK(wait_rv == WAIT_OBJECT_0);
367 BOOL ok = WSAResetEvent(overlapped_.hEvent);
368 CHECK(ok);
369 }
370
382 } // namespace net 371 } // namespace net
383 372
OLDNEW
« net/base/tcp_client_socket.h ('K') | « net/base/tcp_client_socket.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698