Thrift-2029:Port C++ tests to Windows
Client: cpp
Patch: Ben Craig

Updates cpp tests to work with windows and c++11
diff --git a/test/cpp/src/TestServer.cpp b/test/cpp/src/TestServer.cpp
index c99fbac..adb8fd1 100644
--- a/test/cpp/src/TestServer.cpp
+++ b/test/cpp/src/TestServer.cpp
@@ -46,9 +46,11 @@
 #include <boost/program_options.hpp>
 
 #include <signal.h>
+#if _WIN32
+   #include <thrift/windows/TWinsockSingleton.h>
+#endif
 
 using namespace std;
-using namespace boost;
 
 using namespace apache::thrift;
 using namespace apache::thrift::concurrency;
@@ -266,7 +268,7 @@
     (void) arg3;
     (void) arg4;
     (void) arg5;
-    
+
     printf("testMulti()\n");
 
     hello.string_thing = "Hello2";
@@ -314,9 +316,9 @@
     }
   }
 
-  void testOneway(int sleepFor) {
+  void testOneway(const int32_t sleepFor) {
     printf("testOneway(%d): Sleeping...\n", sleepFor);
-    sleep(sleepFor);
+    THRIFT_SLEEP_SEC(sleepFor);
     printf("testOneway(%d): done sleeping!\n", sleepFor);
   }
 };
@@ -447,7 +449,7 @@
   }
 
   virtual void testInsanity(std::tr1::function<void(std::map<UserId, std::map<Numberz::type, Insanity> >  const& _return)> cob, const Insanity& argument) {
-    std::map<UserId, std::map<Numberz::type, Insanity> > res; 
+    std::map<UserId, std::map<Numberz::type, Insanity> > res;
     _delegate->testInsanity(res, argument);
     cob(res);
  }
@@ -490,6 +492,9 @@
 
 
 int main(int argc, char **argv) {
+#if _WIN32
+  transport::TWinsockSingleton::create();
+#endif
   int port = 9090;
   bool ssl = false;
   string transport_type = "buffered";
@@ -498,34 +503,34 @@
   string domain_socket = "";
   size_t workers = 4;
 
- 
-  program_options::options_description desc("Allowed options");
+
+  boost::program_options::options_description desc("Allowed options");
   desc.add_options()
       ("help,h", "produce help message")
-      ("port", program_options::value<int>(&port)->default_value(port), "Port number to listen")
-	  ("domain-socket", program_options::value<string>(&domain_socket)->default_value(domain_socket),
+      ("port", boost::program_options::value<int>(&port)->default_value(port), "Port number to listen")
+	  ("domain-socket", boost::program_options::value<string>(&domain_socket)->default_value(domain_socket),
 	    "Unix Domain Socket (e.g. /tmp/ThriftTest.thrift)")
-      ("server-type", program_options::value<string>(&server_type)->default_value(server_type),
+      ("server-type", boost::program_options::value<string>(&server_type)->default_value(server_type),
         "type of server, \"simple\", \"thread-pool\", \"threaded\", or \"nonblocking\"")
-      ("transport", program_options::value<string>(&transport_type)->default_value(transport_type),
+      ("transport", boost::program_options::value<string>(&transport_type)->default_value(transport_type),
         "transport: buffered, framed, http")
-      ("protocol", program_options::value<string>(&protocol_type)->default_value(protocol_type),
+      ("protocol", boost::program_options::value<string>(&protocol_type)->default_value(protocol_type),
         "protocol: binary, json")
 	  ("ssl", "Encrypted Transport using SSL")
 	  ("processor-events", "processor-events")
-      ("workers,n", program_options::value<size_t>(&workers)->default_value(workers),
+      ("workers,n", boost::program_options::value<size_t>(&workers)->default_value(workers),
         "Number of thread pools workers. Only valid for thread-pool server type")
   ;
 
-  program_options::variables_map vm;
-  program_options::store(program_options::parse_command_line(argc, argv, desc), vm);
-  program_options::notify(vm);    
+  boost::program_options::variables_map vm;
+  boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
+  boost::program_options::notify(vm);
 
   if (vm.count("help")) {
       cout << desc << "\n";
       return 1;
   }
-  
+
   try {
     if (!server_type.empty()) {
       if (server_type == "simple") {
@@ -536,7 +541,7 @@
           throw invalid_argument("Unknown server type "+server_type);
       }
     }
-    
+
     if (!protocol_type.empty()) {
       if (protocol_type == "binary") {
       } else if (protocol_type == "json") {
@@ -562,7 +567,6 @@
 
   if (vm.count("ssl")) {
     ssl = true;
-    signal(SIGPIPE, SIG_IGN);
   }
 
   // Dispatcher
@@ -578,12 +582,12 @@
   // Processor
   boost::shared_ptr<TestHandler> testHandler(new TestHandler());
   boost::shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler));
-  
+
   if (vm.count("processor-events")) {
     testProcessor->setEventHandler(boost::shared_ptr<TProcessorEventHandler>(
           new TestProcessorEventHandler()));
   }
-  
+
   // Transport
   boost::shared_ptr<TSSLSocketFactory> sslSocketFactory;
   boost::shared_ptr<TServerSocket> serverSocket;
@@ -607,15 +611,15 @@
 
   // Factory
   boost::shared_ptr<TTransportFactory> transportFactory;
-  
+
   if (transport_type == "http" && server_type != "nonblocking") {
-    boost::shared_ptr<TTransportFactory> httpTransportFactory(new THttpServerTransportFactory()); 
+    boost::shared_ptr<TTransportFactory> httpTransportFactory(new THttpServerTransportFactory());
     transportFactory = httpTransportFactory;
   } else if (transport_type == "framed") {
-    boost::shared_ptr<TTransportFactory> framedTransportFactory(new TFramedTransportFactory()); 
+    boost::shared_ptr<TTransportFactory> framedTransportFactory(new TFramedTransportFactory());
     transportFactory = framedTransportFactory;
   } else {
-    boost::shared_ptr<TTransportFactory> bufferedTransportFactory(new TBufferedTransportFactory()); 
+    boost::shared_ptr<TTransportFactory> bufferedTransportFactory(new TBufferedTransportFactory());
     transportFactory = bufferedTransportFactory;
   }
 
@@ -628,14 +632,13 @@
   cout << endl;
 
   // Server
+  boost::shared_ptr<apache::thrift::server::TServer> server;
+
   if (server_type == "simple") {
-    TSimpleServer simpleServer(testProcessor,
+    server.reset(new TSimpleServer(testProcessor,
                                serverSocket,
                                transportFactory,
-                               protocolFactory);
-
-    simpleServer.serve();
-
+                               protocolFactory));
   } else if (server_type == "thread-pool") {
 
     boost::shared_ptr<ThreadManager> threadManager =
@@ -648,37 +651,49 @@
 
     threadManager->start();
 
-    TThreadPoolServer threadPoolServer(testProcessor,
+    server.reset(new TThreadPoolServer(testProcessor,
                                        serverSocket,
                                        transportFactory,
                                        protocolFactory,
-                                       threadManager);
-
-    threadPoolServer.serve();
-
+                                       threadManager));
   } else if (server_type == "threaded") {
 
-    TThreadedServer threadedServer(testProcessor,
+    server.reset(new TThreadedServer(testProcessor,
                                    serverSocket,
                                    transportFactory,
-                                   protocolFactory);
-
-    threadedServer.serve();
-
+                                   protocolFactory));
   } else if (server_type == "nonblocking") {
     if(transport_type == "http") {
       boost::shared_ptr<TestHandlerAsync> testHandlerAsync(new TestHandlerAsync(testHandler));
       boost::shared_ptr<TAsyncProcessor> testProcessorAsync(new ThriftTestAsyncProcessor(testHandlerAsync));
       boost::shared_ptr<TAsyncBufferProcessor> testBufferProcessor(new TAsyncProtocolProcessor(testProcessorAsync, protocolFactory));
-      
+
+      // not loading nonblockingServer into "server" because
+      // TEvhttpServer doesn't inherit from TServer, and doesn't
+      // provide a stop method.
       TEvhttpServer nonblockingServer(testBufferProcessor, port);
       nonblockingServer.serve();
-} else {
-      TNonblockingServer nonblockingServer(testProcessor, port);
-      nonblockingServer.serve();
+    } else {
+      server.reset(new TNonblockingServer(testProcessor, port));
     }
   }
 
+  if(server.get() != NULL)
+  {
+    apache::thrift::concurrency::PlatformThreadFactory factory;
+    factory.setDetached(false);
+    boost::shared_ptr<apache::thrift::concurrency::Runnable> serverThreadRunner(server);
+    boost::shared_ptr<apache::thrift::concurrency::Thread> thread = factory.newThread(serverThreadRunner);
+    thread->start();
+
+    cout<<"Press enter to stop the server."<<endl;
+    cin.ignore(); //wait until a key is pressed
+
+    server->stop();
+    thread->join();
+    server.reset();
+  }
+
   cout << "done." << endl;
   return 0;
 }