THRIFT-2838 TNonblockingServer can bind to port 0 (i.e., get an OS-assigned port) but there is no way to get the port number
diff --git a/lib/cpp/src/thrift/server/TNonblockingServer.cpp b/lib/cpp/src/thrift/server/TNonblockingServer.cpp
index 9833f10..a952bf0 100644
--- a/lib/cpp/src/thrift/server/TNonblockingServer.cpp
+++ b/lib/cpp/src/thrift/server/TNonblockingServer.cpp
@@ -1099,6 +1099,16 @@
// Cool, this socket is good to go, set it as the serverSocket_
serverSocket_ = s;
+
+ if (!port_) {
+ sockaddr_in addr;
+ unsigned int size = sizeof(addr);
+ if (!getsockname(serverSocket_, reinterpret_cast<sockaddr*>(&addr), &size)) {
+ listenPort_ = ntohs(addr.sin_port);
+ } else {
+ GlobalOutput.perror("TNonblocking: failed to get listen port: ", THRIFT_GET_SOCKET_ERROR);
+ }
+ }
}
void TNonblockingServer::setThreadManager(boost::shared_ptr<ThreadManager> threadManager) {
@@ -1157,6 +1167,9 @@
}
void TNonblockingServer::stop() {
+ if (!port_) {
+ listenPort_ = 0;
+ }
// Breaks the event loop in all threads so that they end ASAP.
for (uint32_t i = 0; i < ioThreads_.size(); ++i) {
ioThreads_[i]->stop();
@@ -1196,7 +1209,7 @@
assert(ioThreads_.size() > 0);
GlobalOutput.printf("TNonblockingServer: Serving on port %d, %d io threads.",
- port_,
+ listenPort_,
ioThreads_.size());
// Launch all the secondary IO threads in separate threads
diff --git a/lib/cpp/src/thrift/server/TNonblockingServer.h b/lib/cpp/src/thrift/server/TNonblockingServer.h
index 3edc795..4f23487 100644
--- a/lib/cpp/src/thrift/server/TNonblockingServer.h
+++ b/lib/cpp/src/thrift/server/TNonblockingServer.h
@@ -155,9 +155,12 @@
/// Server socket file descriptor
THRIFT_SOCKET serverSocket_;
- /// Port server runs on
+ /// Port server runs on. Zero when letting OS decide actual port
int port_;
+ /// Port server actually runs on
+ int listenPort_;
+
/// The optional user-provided event-base (for single-thread servers)
event_base* userEventBase_;
@@ -280,6 +283,7 @@
nextIOThread_ = 0;
useHighPriorityIOThreads_ = false;
port_ = port;
+ listenPort_ = port;
userEventBase_ = NULL;
threadPoolProcessing_ = false;
numTConnections_ = 0;
@@ -395,6 +399,8 @@
void setThreadManager(boost::shared_ptr<ThreadManager> threadManager);
+ int getListenPort() { return listenPort_; }
+
boost::shared_ptr<ThreadManager> getThreadManager() { return threadManager_; }
/**