Hello,
I found a problem of TSimpleServer: if the client does not close the connection to the server, after the 'stop()' has been called, the TSimpleServer still runs. Here is my code, the environment is thrift-0.7.0@debian 6 x86 32bit. simple.thrift namespace cpp simple service simple_service { string echo(1:string msg) } client.cpp #include <iostream> #include <sstream> #include <string> #include "simple_service.h" #include <transport/TSocket.h> #include <transport/TBufferTransports.h> #include <protocol/TBinaryProtocol.h> using namespace std; using namespace ::apache::thrift; using namespace ::apache::thrift::protocol; using namespace ::apache::thrift::transport; using boost::shared_ptr; using namespace simple; int main(int argc, char **argv) { boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090)); boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket)); boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); simple_serviceClient client(protocol); transport->open(); for (int i=0; i<10000; i++) { stringstream ss; ss << i; string echo, msg(ss.str()); client.echo(echo, msg); cout << "msg=" << msg << " echo=" << echo << endl; sleep(1); } transport->close(); return 0; } server.cpp #include <iostream> #include "simple_service.h" #include <protocol/TBinaryProtocol.h> #include <server/TSimpleServer.h> #include <transport/TServerSocket.h> #include <transport/TBufferTransports.h> #include <concurrency/Thread.h> #include <concurrency/PosixThreadFactory.h> using namespace std; using namespace ::apache::thrift; using namespace ::apache::thrift::protocol; using namespace ::apache::thrift::transport; using namespace ::apache::thrift::server; using namespace ::apache::thrift::concurrency; using boost::shared_ptr; using namespace simple; class simple_serviceHandler : virtual public simple_serviceIf { public: simple_serviceHandler() { // Your initialization goes here } void echo(std::string& _return, const std::string& msg) { _return = msg; } }; class StopTrigger : public Runnable { public: StopTrigger(TSimpleServer *server) : server_(server) { } void run() { // sleep a while and start the client during this short time. sleep(10); cout << "calling TSimpleServer::stop()." << endl; server_->stop(); } private: TSimpleServer *server_; }; int main(int argc, char **argv) { int port = 9090; shared_ptr<simple_serviceHandler> handler(new simple_serviceHandler()); shared_ptr<TProcessor> processor(new simple_serviceProcessor(handler)); shared_ptr<TServerTransport> serverTransport(new TServerSocket(port)); shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory()); shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory); PosixThreadFactory threadFactory = PosixThreadFactory(); threadFactory.setDetached(false); shared_ptr<StopTrigger> stop_trigger(new StopTrigger(&server)); shared_ptr<Thread> stop_thread = threadFactory.newThread(stop_trigger); stop_thread->start(); server.serve(); cout << "the server is stopped" << endl; stop_thread->join(); return 0; } Result: First, I started the server, >./server Then I opened another terminal and started the client with 10 seconds >./client The output of the server is: calling TSimpleServer::stop(). The output of the client is: msg=0 echo=0 msg=1 echo=1 msg=2 echo=2 msg=3 echo=3 msg=4 echo=4 msg=5 echo=5 msg=6 echo=6 msg=7 echo=7 .. We can see that the "the server is stopped" never outputs in the server, which means that the server is not stopped after the 'stop()' has been called. But after I sent a "Ctrl+C" to the client to stop it, the "the server is stopped" printed at last and the server exit. So my conclusion is that: When the client has not closed the connection, the server cannot stop even if the 'stop()' has been called. I checked the source code of TSimpleServer, found that after it accepts the client, it simply loops for ever to process the RPC from client unless the client closes the connection. The 'stop_' variable which is set to 'true' in 'stop()' is ignored in the loop. Here is the code in TSimpleServer.cpp, 99 for (;;) { 100 if (eventHandler_ != NULL) { 101 eventHandler_->processContext(connectionContext, client); 102 } 103 if (!processor_->process(inputProtocol, outputProtocol, connectionContext) || 104 // Peek ahead, is the remote side closed? 105 !inputProtocol->getTransport()->peek()) { 106 break; 107 } 108 } I have a idea to solve this problem: adding the 'stop_' as the loop condition in line:99. 99 for (;stop_;) { ... } I modified the code myself and have tested it, it works fine. So could anyone can give me some suggestions about this issue. Thanks! 2011-09-19 Qianqian JIAO