| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/sync_socket.h" | 5 #include "base/sync_socket.h" | 
| 6 | 6 | 
| 7 #include "base/logging.h" | 7 #include "base/logging.h" | 
| 8 #include "base/win/scoped_handle.h" | 8 #include "base/win/scoped_handle.h" | 
| 9 | 9 | 
| 10 namespace base { | 10 namespace base { | 
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 107 | 107 | 
| 108 // Template function that supports calling ReadFile or WriteFile in an | 108 // Template function that supports calling ReadFile or WriteFile in an | 
| 109 // overlapped fashion and waits for IO completion.  The function also waits | 109 // overlapped fashion and waits for IO completion.  The function also waits | 
| 110 // on an event that can be used to cancel the operation.  If the operation | 110 // on an event that can be used to cancel the operation.  If the operation | 
| 111 // is cancelled, the function returns and closes the relevant socket object. | 111 // is cancelled, the function returns and closes the relevant socket object. | 
| 112 template <typename BufferType, typename Function> | 112 template <typename BufferType, typename Function> | 
| 113 size_t CancelableFileOperation(Function operation, HANDLE file, | 113 size_t CancelableFileOperation(Function operation, HANDLE file, | 
| 114                                BufferType* buffer, size_t length, | 114                                BufferType* buffer, size_t length, | 
| 115                                base::WaitableEvent* io_event, | 115                                base::WaitableEvent* io_event, | 
| 116                                base::WaitableEvent* cancel_event, | 116                                base::WaitableEvent* cancel_event, | 
| 117                                CancelableSyncSocket* socket, | 117                                CancelableSyncSocket* socket) { | 
| 118                                DWORD timeout_in_ms) { |  | 
| 119   // The buffer must be byte size or the length check won't make much sense. | 118   // The buffer must be byte size or the length check won't make much sense. | 
| 120   COMPILE_ASSERT(sizeof(buffer[0]) == sizeof(char), incorrect_buffer_type); | 119   COMPILE_ASSERT(sizeof(buffer[0]) == sizeof(char), incorrect_buffer_type); | 
| 121   DCHECK_LE(length, kMaxMessageLength); | 120   DCHECK_LE(length, kMaxMessageLength); | 
| 122 | 121 | 
| 123   OVERLAPPED ol = {0}; | 122   OVERLAPPED ol = {0}; | 
| 124   ol.hEvent = io_event->handle(); | 123   ol.hEvent = io_event->handle(); | 
| 125   size_t count = 0; | 124   size_t count = 0; | 
| 126   while (count < length) { | 125   while (count < length) { | 
| 127     DWORD chunk = GetNextChunkSize(count, length); | 126     DWORD chunk = GetNextChunkSize(count, length); | 
| 128     // This is either the ReadFile or WriteFile call depending on whether | 127     // This is either the ReadFile or WriteFile call depending on whether | 
| 129     // we're receiving or sending data. | 128     // we're receiving or sending data. | 
| 130     DWORD len = 0; | 129     DWORD len = 0; | 
| 131     BOOL ok = operation(file, static_cast<BufferType*>(buffer) + count, chunk, | 130     BOOL ok = operation(file, static_cast<BufferType*>(buffer) + count, chunk, | 
| 132                         &len, &ol); | 131                         &len, &ol); | 
| 133     if (!ok) { | 132     if (!ok) { | 
| 134       if (::GetLastError() == ERROR_IO_PENDING) { | 133       if (::GetLastError() == ERROR_IO_PENDING) { | 
| 135         HANDLE events[] = { io_event->handle(), cancel_event->handle() }; | 134         base::WaitableEvent* events[] = { io_event, cancel_event }; | 
| 136         int wait_result = WaitForMultipleObjects( | 135         size_t signaled = WaitableEvent::WaitMany(events, arraysize(events)); | 
| 137             arraysize(events), events, FALSE, timeout_in_ms); | 136         if (signaled == 1) { | 
| 138         if (wait_result == (WAIT_OBJECT_0 + 0)) { |  | 
| 139           GetOverlappedResult(file, &ol, &len, TRUE); |  | 
| 140         } else if (wait_result == (WAIT_OBJECT_0 + 1)) { |  | 
| 141           VLOG(1) << "Shutdown was signaled. Closing socket."; | 137           VLOG(1) << "Shutdown was signaled. Closing socket."; | 
| 142           CancelIo(file); | 138           CancelIo(file); | 
| 143           socket->Close(); | 139           socket->Close(); | 
| 144           count = 0; | 140           count = 0; | 
| 145           break; | 141           break; | 
| 146         } else { | 142         } else { | 
| 147           // Timeout happened. | 143           GetOverlappedResult(file, &ol, &len, TRUE); | 
| 148           DCHECK_EQ(WAIT_TIMEOUT, wait_result); |  | 
| 149           if (!CancelIo(file)){ |  | 
| 150             DLOG(WARNING) << "CancelIo() failed"; |  | 
| 151           } |  | 
| 152           break; |  | 
| 153         } | 144         } | 
| 154       } else { | 145       } else { | 
| 155         break; | 146         return (0 < count) ? count : 0; | 
| 156       } | 147       } | 
| 157     } | 148     } | 
| 158 |  | 
| 159     count += len; | 149     count += len; | 
| 160 |  | 
| 161     // Quit the operation if we can't write/read anymore. |  | 
| 162     if (len != chunk) |  | 
| 163       break; |  | 
| 164   } | 150   } | 
| 165 | 151   return count; | 
| 166   return (count > 0) ? count : 0; |  | 
| 167 } | 152 } | 
| 168 | 153 | 
| 169 }  // namespace | 154 }  // namespace | 
| 170 | 155 | 
| 171 const SyncSocket::Handle SyncSocket::kInvalidHandle = INVALID_HANDLE_VALUE; | 156 const SyncSocket::Handle SyncSocket::kInvalidHandle = INVALID_HANDLE_VALUE; | 
| 172 | 157 | 
| 173 SyncSocket::SyncSocket() : handle_(kInvalidHandle) {} | 158 SyncSocket::SyncSocket() : handle_(kInvalidHandle) {} | 
| 174 | 159 | 
| 175 SyncSocket::~SyncSocket() { | 160 SyncSocket::~SyncSocket() { | 
| 176   Close(); | 161   Close(); | 
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 242   return true; | 227   return true; | 
| 243 } | 228 } | 
| 244 | 229 | 
| 245 bool CancelableSyncSocket::Close() { | 230 bool CancelableSyncSocket::Close() { | 
| 246   bool ret = SyncSocket::Close(); | 231   bool ret = SyncSocket::Close(); | 
| 247   shutdown_event_.Reset(); | 232   shutdown_event_.Reset(); | 
| 248   return ret; | 233   return ret; | 
| 249 } | 234 } | 
| 250 | 235 | 
| 251 size_t CancelableSyncSocket::Send(const void* buffer, size_t length) { | 236 size_t CancelableSyncSocket::Send(const void* buffer, size_t length) { | 
| 252   static const DWORD kWaitTimeOutInMs = 500; | 237   return CancelableFileOperation(&WriteFile, handle_, | 
| 253   return CancelableFileOperation( | 238       reinterpret_cast<const char*>(buffer), length, &file_operation_, | 
| 254       &WriteFile, handle_, reinterpret_cast<const char*>(buffer), | 239       &shutdown_event_, this); | 
| 255       length, &file_operation_, &shutdown_event_, this, kWaitTimeOutInMs); |  | 
| 256 } | 240 } | 
| 257 | 241 | 
| 258 size_t CancelableSyncSocket::Receive(void* buffer, size_t length) { | 242 size_t CancelableSyncSocket::Receive(void* buffer, size_t length) { | 
| 259   return CancelableFileOperation(&ReadFile, handle_, | 243   return CancelableFileOperation(&ReadFile, handle_, | 
| 260       reinterpret_cast<char*>(buffer), length, &file_operation_, | 244       reinterpret_cast<char*>(buffer), length, &file_operation_, | 
| 261       &shutdown_event_, this, INFINITE); | 245       &shutdown_event_, this); | 
| 262 } | 246 } | 
| 263 | 247 | 
| 264 // static | 248 // static | 
| 265 bool CancelableSyncSocket::CreatePair(CancelableSyncSocket* socket_a, | 249 bool CancelableSyncSocket::CreatePair(CancelableSyncSocket* socket_a, | 
| 266                                       CancelableSyncSocket* socket_b) { | 250                                       CancelableSyncSocket* socket_b) { | 
| 267   return CreatePairImpl(&socket_a->handle_, &socket_b->handle_, true); | 251   return CreatePairImpl(&socket_a->handle_, &socket_b->handle_, true); | 
| 268 } | 252 } | 
| 269 | 253 | 
| 270 | 254 | 
| 271 }  // namespace base | 255 }  // namespace base | 
| OLD | NEW | 
|---|