Server robustness fixes in Thrift C++ libs

Summary: ServerSockets can be interrupt() ed

Reviewed By: marc, karl


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665039 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/server/TSimpleServer.cpp b/lib/cpp/src/server/TSimpleServer.cpp
index 8657fab..e7d7e9b 100644
--- a/lib/cpp/src/server/TSimpleServer.cpp
+++ b/lib/cpp/src/server/TSimpleServer.cpp
@@ -57,21 +57,21 @@
       outputTransport->close();
       client->close();    
     } catch (TTransportException& ttx) {
-      inputTransport->close();
-      outputTransport->close();
-      client->close();
+      if (inputTransport.get() != NULL) { inputTransport->close(); }
+      if (outputTransport.get() != NULL) { outputTransport->close(); }
+      if (client.get() != NULL) { client->close(); }
       cerr << "TServerTransport died on accept: " << ttx.what() << endl;
       continue;
     } catch (TException& tx) {
-      inputTransport->close();
-      outputTransport->close();
-      client->close();
+      if (inputTransport.get() != NULL) { inputTransport->close(); }
+      if (outputTransport.get() != NULL) { outputTransport->close(); }
+      if (client.get() != NULL) { client->close(); }
       cerr << "Some kind of accept exception: " << tx.what() << endl;
       continue;
     } catch (string s) {
-      inputTransport->close();
-      outputTransport->close();
-      client->close();
+      if (inputTransport.get() != NULL) { inputTransport->close(); }
+      if (outputTransport.get() != NULL) { outputTransport->close(); }
+      if (client.get() != NULL) { client->close(); }
       cerr << "TThreadPoolServer: Unknown exception: " << s << endl;
       break;
     }
diff --git a/lib/cpp/src/server/TThreadPoolServer.cpp b/lib/cpp/src/server/TThreadPoolServer.cpp
index 32a0223..dcbf2f2 100644
--- a/lib/cpp/src/server/TThreadPoolServer.cpp
+++ b/lib/cpp/src/server/TThreadPoolServer.cpp
@@ -102,6 +102,7 @@
     try {
       // Fetch client from server
       client = serverTransport_->accept();
+
       // Make IO transports
       inputTransport = inputTransportFactory_->getTransport(client);
       outputTransport = outputTransportFactory_->getTransport(client);
@@ -109,25 +110,26 @@
       outputProtocol = outputProtocolFactory_->getProtocol(outputTransport);
 
       // Add to threadmanager pool
-      threadManager_->add(shared_ptr<TThreadPoolServer::Task>(new TThreadPoolServer::Task(processor_, 
-                                                                                          inputProtocol, 
-                                                                                          outputProtocol)));
+      threadManager_->add(shared_ptr<TThreadPoolServer::Task>(new TThreadPoolServer::Task(processor_, inputProtocol, outputProtocol)));
+
     } catch (TTransportException& ttx) {
-      inputTransport->close();
-      outputTransport->close();
-      client->close();
-      cerr << "TThreadPoolServer: TServerTransport died on accept: " << ttx.what() << endl;
+      if (inputTransport.get() != NULL) { inputTransport->close(); }
+      if (outputTransport.get() != NULL) { outputTransport->close(); }
+      if (client.get() != NULL) { client->close(); }
+      if (!stop_ || ttx.getType() != TTransportException::INTERRUPTED) {
+        cerr << "TThreadPoolServer: TServerTransport died on accept: " << ttx.what() << endl;
+      }
       continue;
     } catch (TException& tx) {
-      inputTransport->close();
-      outputTransport->close();
-      client->close();
+      if (inputTransport.get() != NULL) { inputTransport->close(); }
+      if (outputTransport.get() != NULL) { outputTransport->close(); }
+      if (client.get() != NULL) { client->close(); }
       cerr << "TThreadPoolServer: Caught TException: " << tx.what() << endl;
       continue;
     } catch (string s) {
-      inputTransport->close();
-      outputTransport->close();
-      client->close();
+      if (inputTransport.get() != NULL) { inputTransport->close(); }
+      if (outputTransport.get() != NULL) { outputTransport->close(); }
+      if (client.get() != NULL) { client->close(); }
       cerr << "TThreadPoolServer: Unknown exception: " << s << endl;
       break;
     }
@@ -141,8 +143,8 @@
     } catch (TException &tx) {
       cerr << "TThreadPoolServer: Exception shutting down: " << tx.what() << endl;
     }
+    stop_ = false;
   }
-  stop_ = false;
 
 }
 
diff --git a/lib/cpp/src/server/TThreadPoolServer.h b/lib/cpp/src/server/TThreadPoolServer.h
index f6809fc..bdb0e47 100644
--- a/lib/cpp/src/server/TThreadPoolServer.h
+++ b/lib/cpp/src/server/TThreadPoolServer.h
@@ -41,7 +41,10 @@
 
   virtual void serve();
   
-  virtual void stop() { stop_ = true; }
+  virtual void stop() {
+    stop_ = true;
+    serverTransport_->interrupt();
+  }
 
  protected: