Fix truncated large transfers.

When the send pipe is closed, we can and should continue to write out
to the socket.

BUG=https://github.com/domokit/mojo/issues/253
R=viettrungluu@chromium.org

Review URL: https://codereview.chromium.org/1192703002.
diff --git a/mojo/services/network/tcp_connected_socket_impl.cc b/mojo/services/network/tcp_connected_socket_impl.cc
index bc8c98b..7a46529 100644
--- a/mojo/services/network/tcp_connected_socket_impl.cc
+++ b/mojo/services/network/tcp_connected_socket_impl.cc
@@ -19,6 +19,7 @@
       send_stream_(send_stream.Pass()),
       receive_stream_(receive_stream.Pass()),
       binding_(this, request.Pass()),
+      send_more_posted_(false),
       weak_ptr_factory_(this) {
   // Queue up async communication.
   binding_.set_error_handler(this);
@@ -149,6 +150,11 @@
   ShutdownReceive();
 }
 
+void TCPConnectedSocketImpl::SendMoreAsync() {
+  send_more_posted_ = false;
+  SendMore();
+}
+
 void TCPConnectedSocketImpl::SendMore() {
   uint32_t num_bytes = 0;
   MojoResult result = MojoToNetPendingBuffer::BeginRead(
@@ -217,9 +223,11 @@
   // Schedule more writing.
   if (completed_synchronously) {
     // Don't recursively call SendMore if this is a sync read.
+    DCHECK(!send_more_posted_);
+    send_more_posted_ = true;
     base::MessageLoop::current()->PostTask(
-        FROM_HERE, base::Bind(&TCPConnectedSocketImpl::SendMore,
-                              weak_ptr_factory_.GetWeakPtr()));
+      FROM_HERE, base::Bind(&TCPConnectedSocketImpl::SendMoreAsync,
+                            weak_ptr_factory_.GetWeakPtr()));
   } else {
     SendMore();
   }
@@ -241,7 +249,10 @@
 }
 
 void TCPConnectedSocketImpl::OnSendDataPipeClosed(MojoResult result) {
-  ShutdownSend();
+  // If there's a send in progress, let it complete.  In that case,
+  // ShutdownSend will be called when there is no more data to read.
+  if (!pending_send_ && !send_more_posted_)
+    ShutdownSend();
 }
 
 void TCPConnectedSocketImpl::DeleteIfNeeded() {
diff --git a/mojo/services/network/tcp_connected_socket_impl.h b/mojo/services/network/tcp_connected_socket_impl.h
index 6e71499..0fed4d0 100644
--- a/mojo/services/network/tcp_connected_socket_impl.h
+++ b/mojo/services/network/tcp_connected_socket_impl.h
@@ -41,6 +41,7 @@
   // "Writing" is reading from the Mojo send_stream and writing to the
   // TCPSocket.
   void SendMore();
+  void SendMoreAsync();
   void OnSendStreamReady(MojoResult result);
   void DidSend(bool completed_asynchronously, int result);
   void ShutdownSend();
@@ -68,6 +69,8 @@
   // To bind to the message pipe.
   Binding<TCPConnectedSocket> binding_;
 
+  bool send_more_posted_;
+
   base::WeakPtrFactory<TCPConnectedSocketImpl> weak_ptr_factory_;
 };