| Index: mojo/services/network/tcp_connected_socket_impl.cc
|
| diff --git a/mojo/services/network/tcp_connected_socket_impl.cc b/mojo/services/network/tcp_connected_socket_impl.cc
|
| index 9e8a9a9703e406881f185bb2e5725b86e15d7f40..641f1c32a607b351fe599a177f8855480a5ad86c 100644
|
| --- a/mojo/services/network/tcp_connected_socket_impl.cc
|
| +++ b/mojo/services/network/tcp_connected_socket_impl.cc
|
| @@ -36,7 +36,8 @@ void TCPConnectedSocketImpl::ReceiveMore() {
|
| // The pipe is full. We need to wait for it to have more space.
|
| receive_handle_watcher_.Start(
|
| receive_stream_.get(),
|
| - MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE,
|
| + MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
|
| + MOJO_DEADLINE_INDEFINITE,
|
| base::Bind(&TCPConnectedSocketImpl::OnReceiveStreamReady,
|
| weak_ptr_factory_.GetWeakPtr()));
|
| return;
|
| @@ -46,12 +47,17 @@ void TCPConnectedSocketImpl::ReceiveMore() {
|
| // It's valid that the user of this class consumed the data they care about
|
| // and closed their data pipe handles after writing data. This class should
|
| // still write out all the data.
|
| + ShutdownReceive();
|
| + // TODO(johnmccutchan): Notify socket direction is closed along with
|
| + // net_result and mojo_result.
|
| return;
|
| }
|
|
|
| if (result != MOJO_RESULT_OK) {
|
| // The receive stream is in a bad state.
|
| - // TODO(darin): How should this be communicated to our client?
|
| + ShutdownReceive();
|
| + // TODO(johnmccutchan): Notify socket direction is closed along with
|
| + // net_result and mojo_result.
|
| return;
|
| }
|
|
|
| @@ -65,17 +71,25 @@ void TCPConnectedSocketImpl::ReceiveMore() {
|
| false));
|
| if (read_result == net::ERR_IO_PENDING) {
|
| // Pending I/O, wait for result in DidReceive().
|
| - } else if (read_result >= 0) {
|
| + } else if (read_result > 0) {
|
| // Synchronous data ready.
|
| DidReceive(true, read_result);
|
| } else {
|
| - // Some kind of error.
|
| - // TODO(brettw) notify caller of error.
|
| + // read_result == 0 indicates EOF.
|
| + // read_result < 0 indicates error.
|
| + ShutdownReceive();
|
| + // TODO(johnmccutchan): Notify socket direction is closed along with
|
| + // net_result and mojo_result.
|
| }
|
| }
|
|
|
| void TCPConnectedSocketImpl::OnReceiveStreamReady(MojoResult result) {
|
| - // TODO(darin): Handle a bad |result| value.
|
| + if (result != MOJO_RESULT_OK) {
|
| + ShutdownReceive();
|
| + // TODO(johnmccutchan): Notify socket direction is closed along with
|
| + // net_result and mojo_result.
|
| + return;
|
| + }
|
| ReceiveMore();
|
| }
|
|
|
| @@ -83,13 +97,14 @@ void TCPConnectedSocketImpl::DidReceive(bool completed_synchronously,
|
| int result) {
|
| if (result < 0) {
|
| // Error.
|
| - pending_receive_ = NULL; // Closes the pipe (owned by the pending write).
|
| - // TODO(brettw) notify the caller of an error?
|
| + ShutdownReceive();
|
| + // TODO(johnmccutchan): Notify socket direction is closed along with
|
| + // net_result and mojo_result.
|
| return;
|
| }
|
|
|
| receive_stream_ = pending_receive_->Complete(result);
|
| - pending_receive_ = NULL;
|
| + pending_receive_ = nullptr;
|
|
|
| // Schedule more reading.
|
| if (completed_synchronously) {
|
| @@ -103,6 +118,11 @@ void TCPConnectedSocketImpl::DidReceive(bool completed_synchronously,
|
| }
|
| }
|
|
|
| +void TCPConnectedSocketImpl::ShutdownReceive() {
|
| + pending_receive_ = nullptr;
|
| + receive_stream_.reset();
|
| +}
|
| +
|
| void TCPConnectedSocketImpl::SendMore() {
|
| uint32_t num_bytes = 0;
|
| MojoResult result = MojoToNetPendingBuffer::BeginRead(
|
| @@ -111,12 +131,15 @@ void TCPConnectedSocketImpl::SendMore() {
|
| // Data not ready, wait for it.
|
| send_handle_watcher_.Start(
|
| send_stream_.get(),
|
| - MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
|
| + MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
|
| + MOJO_DEADLINE_INDEFINITE,
|
| base::Bind(&TCPConnectedSocketImpl::OnSendStreamReady,
|
| weak_ptr_factory_.GetWeakPtr()));
|
| return;
|
| } else if (result != MOJO_RESULT_OK) {
|
| - // TODO(brettw) notify caller of error.
|
| + ShutdownSend();
|
| + // TODO(johnmccutchan): Notify socket direction is closed along with
|
| + // net_result and mojo_result.
|
| return;
|
| }
|
|
|
| @@ -132,25 +155,36 @@ void TCPConnectedSocketImpl::SendMore() {
|
| } else if (write_result >= 0) {
|
| // Synchronous data consumed.
|
| DidSend(true, write_result);
|
| + } else {
|
| + // write_result < 0 indicates error.
|
| + ShutdownSend();
|
| + // TODO(johnmccutchan): Notify socket direction is closed along with
|
| + // net_result and mojo_result.
|
| }
|
| }
|
|
|
| void TCPConnectedSocketImpl::OnSendStreamReady(MojoResult result) {
|
| - // TODO(brettw): Handle a bad |result| value.
|
| + if (result != MOJO_RESULT_OK) {
|
| + ShutdownSend();
|
| + // TODO(johnmccutchan): Notify socket direction is closed along with
|
| + // net_result and mojo_result.
|
| + return;
|
| + }
|
| SendMore();
|
| }
|
|
|
| void TCPConnectedSocketImpl::DidSend(bool completed_synchronously,
|
| int result) {
|
| if (result < 0) {
|
| - // TODO(brettw) report error.
|
| - pending_send_ = NULL;
|
| + ShutdownSend();
|
| + // TODO(johnmccutchan): Notify socket direction is closed along with
|
| + // net_result and mojo_result.
|
| return;
|
| }
|
|
|
| // Take back ownership of the stream and free the IOBuffer.
|
| send_stream_ = pending_send_->Complete(result);
|
| - pending_send_ = NULL;
|
| + pending_send_ = nullptr;
|
|
|
| // Schedule more writing.
|
| if (completed_synchronously) {
|
| @@ -164,4 +198,9 @@ void TCPConnectedSocketImpl::DidSend(bool completed_synchronously,
|
| }
|
| }
|
|
|
| +void TCPConnectedSocketImpl::ShutdownSend() {
|
| + pending_send_ = nullptr;
|
| + send_stream_.reset();
|
| +}
|
| +
|
| } // namespace mojo
|
|
|