You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by br...@apache.org on 2011/08/24 23:26:48 UTC
svn commit: r1161283 - in /thrift/trunk/lib/cpp/src/server:
TNonblockingServer.cpp TNonblockingServer.h
Author: bryanduxbury
Date: Wed Aug 24 21:26:48 2011
New Revision: 1161283
URL: http://svn.apache.org/viewvc?rev=1161283&view=rev
Log:
THRIFT-1289. cpp: implement TNonblockingServer::stop()
Patch: Adam Simpkins
Modified:
thrift/trunk/lib/cpp/src/server/TNonblockingServer.cpp
thrift/trunk/lib/cpp/src/server/TNonblockingServer.h
Modified: thrift/trunk/lib/cpp/src/server/TNonblockingServer.cpp
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/cpp/src/server/TNonblockingServer.cpp?rev=1161283&r1=1161282&r2=1161283&view=diff
==============================================================================
--- thrift/trunk/lib/cpp/src/server/TNonblockingServer.cpp (original)
+++ thrift/trunk/lib/cpp/src/server/TNonblockingServer.cpp Wed Aug 24 21:26:48 2011
@@ -30,6 +30,7 @@
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#include <netinet/tcp.h>
+#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
@@ -919,8 +920,47 @@ void TNonblockingServer::serve() {
eventHandler_->preServe();
}
- // Run libevent engine, never returns, invokes calls to eventHandler
+ // Run libevent engine, invokes calls to eventHandler
+ // Only returns if stop() is called.
event_base_loop(eventBase_, 0);
}
+void TNonblockingServer::stop() {
+ if (!eventBase_) {
+ return;
+ }
+
+ // Call event_base_loopbreak() to tell libevent to exit the loop
+ //
+ // (The libevent documentation doesn't explicitly state that this function is
+ // safe to call from another thread. However, all it does is set a variable,
+ // in the event_base, so it should be fine.)
+ event_base_loopbreak(eventBase_);
+
+ // event_base_loopbreak() only causes the loop to exit the next time it wakes
+ // up. We need to force it to wake up, in case there are no real events
+ // it needs to process.
+ //
+ // Attempt to connect to the server socket. If anything fails,
+ // we'll just have to wait until libevent wakes up on its own.
+ //
+ // First create a socket
+ int fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (fd < 0) {
+ return;
+ }
+
+ // Set up the address
+ struct sockaddr_in addr;
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(0x7f000001); // 127.0.0.1
+ addr.sin_port = htons(port_);
+
+ // Finally do the connect().
+ // We don't care about the return value;
+ // we're just going to close the socket either way.
+ connect(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr));
+ close(fd);
+}
+
}}} // apache::thrift::server
Modified: thrift/trunk/lib/cpp/src/server/TNonblockingServer.h
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/cpp/src/server/TNonblockingServer.h?rev=1161283&r1=1161282&r2=1161283&view=diff
==============================================================================
--- thrift/trunk/lib/cpp/src/server/TNonblockingServer.h (original)
+++ thrift/trunk/lib/cpp/src/server/TNonblockingServer.h Wed Aug 24 21:26:48 2011
@@ -718,6 +718,11 @@ class TNonblockingServer : public TServe
* loops over the libevent handler.
*/
void serve();
+
+ /**
+ * May be called from a separate thread to cause serve() to return.
+ */
+ void stop();
};
/// Three states for sockets: recv frame size, recv data, and send mode