Index: extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc |
diff --git a/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc b/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc |
index 83124b0cf2fff4d860b0cba4928a4be7f63eb3f9..9f30a7719baf4b416a03373729087a2b376ab064 100644 |
--- a/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc |
+++ b/extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.cc |
@@ -115,6 +115,9 @@ void TCPSocketEventDispatcher::ReadCallback( |
int bytes_read, |
scoped_refptr<net::IOBuffer> io_buffer) { |
DCHECK_CURRENTLY_ON(params.thread_id); |
+ ResumableTCPSocket* socket = |
+ params.sockets->Get(params.extension_id, params.socket_id); |
+ bool socket_paused = socket != NULL && socket->paused(); |
// If |bytes_read| == 0, the connection has been closed by the peer. |
// If |bytes_read| < 0, there was a network error, and |bytes_read| is a value |
@@ -145,6 +148,12 @@ void TCPSocketEventDispatcher::ReadCallback( |
} else if (bytes_read == net::ERR_IO_PENDING) { |
// This happens when resuming a socket which already had an |
// active "read" callback. |
+ } else if (bytes_read == net::ERR_ABORTED && socket_paused) { |
+ // This happens when a socket has been paused by the |
+ // sockets_tcp.setPaused() API. The Read() was canceled on purpose. Let |
+ // the socket know that the API-invoked pause process has completed. Do |
+ // not dispatch an "onReceiveError" as there was no real error. |
+ socket->ApiPauseComplete(); |
} else { |
// Dispatch "onReceiveError" event but don't start another read to avoid |
// potential infinite reads if we have a persistent network error. |
@@ -157,7 +166,6 @@ void TCPSocketEventDispatcher::ReadCallback( |
sockets_tcp::OnReceiveError::kEventName, |
args.Pass())); |
PostEvent(params, event.Pass()); |
- |
// Since we got an error, the socket is now "paused" until the application |
// "resumes" it. |
ResumableTCPSocket* socket = |
@@ -172,13 +180,10 @@ void TCPSocketEventDispatcher::ReadCallback( |
void TCPSocketEventDispatcher::PostEvent(const ReadParams& params, |
scoped_ptr<Event> event) { |
DCHECK_CURRENTLY_ON(params.thread_id); |
- |
- BrowserThread::PostTask(BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&DispatchEvent, |
- params.browser_context_id, |
- params.extension_id, |
- base::Passed(event.Pass()))); |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(&DispatchEvent, params.browser_context_id, params.extension_id, |
+ base::Passed(event.Pass()))); |
} |
// static |
@@ -189,12 +194,14 @@ void TCPSocketEventDispatcher::DispatchEvent(void* browser_context_id, |
content::BrowserContext* context = |
reinterpret_cast<content::BrowserContext*>(browser_context_id); |
- if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context)) |
+ if (!extensions::ExtensionsBrowserClient::Get()->IsValidContext(context)) { |
return; |
+ } |
EventRouter* event_router = EventRouter::Get(context); |
- if (event_router) |
+ if (event_router) { |
event_router->DispatchEventToExtension(extension_id, event.Pass()); |
+ } |
} |
} // namespace api |