diff options
author | xians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-19 10:23:03 +0000 |
---|---|---|
committer | xians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-19 10:23:03 +0000 |
commit | 5d272095550875715eb8eec5719f88dc2bd48113 (patch) | |
tree | e3837dc4b977b97d509f7e2ffd98a4e470050926 /base/sync_socket_win.cc | |
parent | 20a6dd7b935444ee84f431dd186501accce3ca39 (diff) | |
download | chromium_src-5d272095550875715eb8eec5719f88dc2bd48113.zip chromium_src-5d272095550875715eb8eec5719f88dc2bd48113.tar.gz chromium_src-5d272095550875715eb8eec5719f88dc2bd48113.tar.bz2 |
Revert revert 132842
If we are using blocking write, when the renderer stop getting the data without notifying the browser, it will hang the browser. This happens with some plugins which use the sync sockets provided by the Pepper.
This patch change CancellableSyncSocket to be non-blocking on sending, so that we don't need to worry the whole browser hangs by one plugin application.
Also, we remove the lock in audio_sync_reader.cc since it is not really needed if we don't set the socket_ to NULL when calling Close(). By doing this we allow the user to close the socket while another thread is writing to the socket.
BUG=121152
TEST=ipc_tests
TBR=tommi@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10124004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132975 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/sync_socket_win.cc')
-rw-r--r-- | base/sync_socket_win.cc | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/base/sync_socket_win.cc b/base/sync_socket_win.cc index c6fb1ce..4fcd572 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 |