THRIFT-5078 Handle named pipe clients quickly disconnecting
Client: C++
Patch: Nick Collier

This closes #1964
diff --git a/lib/cpp/src/thrift/server/TServerFramework.cpp b/lib/cpp/src/thrift/server/TServerFramework.cpp
index 35f3b25..302cbf1 100644
--- a/lib/cpp/src/thrift/server/TServerFramework.cpp
+++ b/lib/cpp/src/thrift/server/TServerFramework.cpp
@@ -166,8 +166,9 @@
       releaseOneDescriptor("inputTransport", inputTransport);
       releaseOneDescriptor("outputTransport", outputTransport);
       releaseOneDescriptor("client", client);
-      if (ttx.getType() == TTransportException::TIMED_OUT) {
-        // Accept timeout - continue processing.
+      if (ttx.getType() == TTransportException::TIMED_OUT
+          || ttx.getType() == TTransportException::CLIENT_DISCONNECT) {
+        // Accept timeout and client disconnect - continue processing.
         continue;
       } else if (ttx.getType() == TTransportException::END_OF_FILE
                  || ttx.getType() == TTransportException::INTERRUPTED) {
diff --git a/lib/cpp/src/thrift/transport/TPipeServer.cpp b/lib/cpp/src/thrift/transport/TPipeServer.cpp
index 47d8822..f0d1e70 100644
--- a/lib/cpp/src/thrift/transport/TPipeServer.cpp
+++ b/lib/cpp/src/thrift/transport/TPipeServer.cpp
@@ -286,8 +286,20 @@
   // concurrently with interrupt, and that should be fine.
   if (GetOverlappedResult(Pipe_.h, &connectOverlap_.overlap, &dwDummy, TRUE)) {
     TAutoCrit lock(pipe_protect_);
+    shared_ptr<TPipe> client;
+    try {
+      client.reset(new TPipe(Pipe_));
+    } catch (TTransportException& ttx) {
+      if (ttx.getType() == TTransportException::INTERRUPTED) {
+        throw;
+      }
+
+      GlobalOutput.perror("Client connection failed. TTransportExceptionType=", ttx.getType());
+      // kick off the next connection before throwing
+      initiateNamedConnect(lock);
+      throw TTransportException(TTransportException::CLIENT_DISCONNECT, ttx.what());
+    }
     GlobalOutput.printf("Client connected.");
-    shared_ptr<TPipe> client(new TPipe(Pipe_));
     // kick off the next connection before returning
     initiateNamedConnect(lock);
     return client; // success!
diff --git a/lib/cpp/src/thrift/transport/TTransportException.h b/lib/cpp/src/thrift/transport/TTransportException.h
index 38b7521..dd5f361 100644
--- a/lib/cpp/src/thrift/transport/TTransportException.h
+++ b/lib/cpp/src/thrift/transport/TTransportException.h
@@ -49,7 +49,8 @@
     INTERRUPTED = 4,
     BAD_ARGS = 5,
     CORRUPTED_DATA = 6,
-    INTERNAL_ERROR = 7
+    INTERNAL_ERROR = 7,
+    CLIENT_DISCONNECT = 8
   };
 
   TTransportException() : apache::thrift::TException(), type_(UNKNOWN) {}