| Index: base/sync_socket_win.cc
|
| diff --git a/base/sync_socket_win.cc b/base/sync_socket_win.cc
|
| index c6fb1ce789c4b7fe596f8cccd99e704ec1d0713c..4fcd572084f72abc38d6b035873c6fa27ff93887 100644
|
| --- a/base/sync_socket_win.cc
|
| +++ b/base/sync_socket_win.cc
|
| @@ -114,7 +114,8 @@ size_t CancelableFileOperation(Function operation, HANDLE file,
|
| BufferType* buffer, size_t length,
|
| base::WaitableEvent* io_event,
|
| base::WaitableEvent* cancel_event,
|
| - CancelableSyncSocket* socket) {
|
| + CancelableSyncSocket* socket,
|
| + DWORD timeout_in_ms) {
|
| // The buffer must be byte size or the length check won't make much sense.
|
| COMPILE_ASSERT(sizeof(buffer[0]) == sizeof(char), incorrect_buffer_type);
|
| DCHECK_LE(length, kMaxMessageLength);
|
| @@ -131,24 +132,38 @@ size_t CancelableFileOperation(Function operation, HANDLE file,
|
| &len, &ol);
|
| if (!ok) {
|
| if (::GetLastError() == ERROR_IO_PENDING) {
|
| - base::WaitableEvent* events[] = { io_event, cancel_event };
|
| - size_t signaled = WaitableEvent::WaitMany(events, arraysize(events));
|
| - if (signaled == 1) {
|
| + HANDLE events[] = { io_event->handle(), cancel_event->handle() };
|
| + int wait_result = WaitForMultipleObjects(
|
| + arraysize(events), events, FALSE, timeout_in_ms);
|
| + if (wait_result == (WAIT_OBJECT_0 + 0)) {
|
| + GetOverlappedResult(file, &ol, &len, TRUE);
|
| + } else if (wait_result == (WAIT_OBJECT_0 + 1)) {
|
| VLOG(1) << "Shutdown was signaled. Closing socket.";
|
| CancelIo(file);
|
| socket->Close();
|
| count = 0;
|
| break;
|
| } else {
|
| - GetOverlappedResult(file, &ol, &len, TRUE);
|
| + // Timeout happened.
|
| + DCHECK_EQ(WAIT_TIMEOUT, wait_result);
|
| + if (!CancelIo(file)){
|
| + DLOG(WARNING) << "CancelIo() failed";
|
| + }
|
| + break;
|
| }
|
| } else {
|
| - return (0 < count) ? count : 0;
|
| + break;
|
| }
|
| }
|
| +
|
| count += len;
|
| +
|
| + // Quit the operation if we can't write/read anymore.
|
| + if (len != chunk)
|
| + break;
|
| }
|
| - return count;
|
| +
|
| + return (count > 0) ? count : 0;
|
| }
|
|
|
| } // namespace
|
| @@ -234,15 +249,16 @@ bool CancelableSyncSocket::Close() {
|
| }
|
|
|
| size_t CancelableSyncSocket::Send(const void* buffer, size_t length) {
|
| - return CancelableFileOperation(&WriteFile, handle_,
|
| - reinterpret_cast<const char*>(buffer), length, &file_operation_,
|
| - &shutdown_event_, this);
|
| + static const DWORD kWaitTimeOutInMs = 500;
|
| + return CancelableFileOperation(
|
| + &WriteFile, handle_, reinterpret_cast<const char*>(buffer),
|
| + length, &file_operation_, &shutdown_event_, this, kWaitTimeOutInMs);
|
| }
|
|
|
| size_t CancelableSyncSocket::Receive(void* buffer, size_t length) {
|
| return CancelableFileOperation(&ReadFile, handle_,
|
| reinterpret_cast<char*>(buffer), length, &file_operation_,
|
| - &shutdown_event_, this);
|
| + &shutdown_event_, this, INFINITE);
|
| }
|
|
|
| // static
|
|
|