Add isOpen() to TServerTransport

Client: cpp
diff --git a/lib/cpp/src/thrift/transport/TPipeServer.cpp b/lib/cpp/src/thrift/transport/TPipeServer.cpp
index f0d1e70..0855e2c 100644
--- a/lib/cpp/src/thrift/transport/TPipeServer.cpp
+++ b/lib/cpp/src/thrift/transport/TPipeServer.cpp
@@ -181,6 +181,10 @@
 //---- Destructor ----
 TPipeServer::~TPipeServer() {}
 
+bool TPipeServer::isOpen() const {
+  return (impl_->getPipeHandle() != INVALID_HANDLE_VALUE);
+}
+
 //---------------------------------------------------------
 // Transport callbacks
 //---------------------------------------------------------
diff --git a/lib/cpp/src/thrift/transport/TPipeServer.h b/lib/cpp/src/thrift/transport/TPipeServer.h
index 871b6af..d4255cb 100644
--- a/lib/cpp/src/thrift/transport/TPipeServer.h
+++ b/lib/cpp/src/thrift/transport/TPipeServer.h
@@ -59,6 +59,8 @@
   // Destructor
   virtual ~TPipeServer();
 
+  bool isOpen() const override;
+
   // Standard transport callbacks
   void interrupt() override;
   void close() override;
diff --git a/lib/cpp/src/thrift/transport/TServerSocket.cpp b/lib/cpp/src/thrift/transport/TServerSocket.cpp
index ece0544..1bc6b47 100644
--- a/lib/cpp/src/thrift/transport/TServerSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TServerSocket.cpp
@@ -185,6 +185,10 @@
   close();
 }
 
+bool TServerSocket::isOpen() const {
+  return (serverSocket_ != THRIFT_INVALID_SOCKET);
+}
+
 void TServerSocket::setSendTimeout(int sendTimeout) {
   sendTimeout_ = sendTimeout;
 }
diff --git a/lib/cpp/src/thrift/transport/TServerSocket.h b/lib/cpp/src/thrift/transport/TServerSocket.h
index d640968..4562341 100644
--- a/lib/cpp/src/thrift/transport/TServerSocket.h
+++ b/lib/cpp/src/thrift/transport/TServerSocket.h
@@ -98,6 +98,9 @@
 
   ~TServerSocket() override;
 
+
+  bool isOpen() const override;
+
   void setSendTimeout(int sendTimeout);
   void setRecvTimeout(int recvTimeout);
 
diff --git a/lib/cpp/src/thrift/transport/TServerTransport.h b/lib/cpp/src/thrift/transport/TServerTransport.h
index f465bb3..9e84850 100644
--- a/lib/cpp/src/thrift/transport/TServerTransport.h
+++ b/lib/cpp/src/thrift/transport/TServerTransport.h
@@ -38,6 +38,11 @@
   virtual ~TServerTransport() = default;
 
   /**
+   * Whether this transport is open.
+   */
+  virtual bool isOpen() const { return false; }
+
+  /**
    * Starts the server transport listening for new connections. Prior to this
    * call most transports will not return anything when accept is called.
    *
diff --git a/lib/cpp/test/TServerSocketTest.cpp b/lib/cpp/test/TServerSocketTest.cpp
index bec6d47..c96700f 100644
--- a/lib/cpp/test/TServerSocketTest.cpp
+++ b/lib/cpp/test/TServerSocketTest.cpp
@@ -35,6 +35,7 @@
 BOOST_AUTO_TEST_CASE(test_bind_to_address) {
   TServerSocket sock1("localhost", 0);
   sock1.listen();
+  BOOST_CHECK(sock1.isOpen());
   int port = sock1.getPort();
   TSocket clientSock("localhost", port);
   clientSock.open();
@@ -48,17 +49,20 @@
   sock2.close();
 }
 
-BOOST_AUTO_TEST_CASE(test_listen_valid_port) {
+BOOST_AUTO_TEST_CASE(test_listen_invalid_port) {
   TServerSocket sock1(-1);
   TTRANSPORT_CHECK_THROW(sock1.listen(), TTransportException::BAD_ARGS);
+  BOOST_CHECK(!sock1.isOpen());
 
   TServerSocket sock2(65536);
   TTRANSPORT_CHECK_THROW(sock2.listen(), TTransportException::BAD_ARGS);
+  BOOST_CHECK(!sock1.isOpen());
 }
 
 BOOST_AUTO_TEST_CASE(test_close_before_listen) {
   TServerSocket sock1("localhost", 0);
   sock1.close();
+  BOOST_CHECK(!sock1.isOpen());
 }
 
 BOOST_AUTO_TEST_CASE(test_get_port) {
diff --git a/lib/cpp/test/TSocketInterruptTest.cpp b/lib/cpp/test/TSocketInterruptTest.cpp
index 366242f..a546c23 100644
--- a/lib/cpp/test/TSocketInterruptTest.cpp
+++ b/lib/cpp/test/TSocketInterruptTest.cpp
@@ -53,6 +53,7 @@
 BOOST_AUTO_TEST_CASE(test_interruptable_child_read) {
   TServerSocket sock1("localhost", 0);
   sock1.listen();
+  BOOST_CHECK(sock1.isOpen());
   int port = sock1.getPort();
   TSocket clientSock("localhost", port);
   clientSock.open();