1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 #ifndef _THRIFT_TEST_SERVERTHREAD_H_ 20 #define _THRIFT_TEST_SERVERTHREAD_H_ 1 21 22 #include <thrift/TProcessor.h> 23 #include <thrift/protocol/TProtocol.h> 24 #include <thrift/server/TServer.h> 25 #include <thrift/transport/TTransport.h> 26 27 #include "EventLog.h" 28 29 namespace apache { 30 namespace thrift { 31 namespace test { 32 33 /** 34 * A helper class to tell ServerThread how to create the server 35 */ 36 class ServerState { 37 public: 38 virtual ~ServerState() = default; 39 40 /** 41 * Create a server to listen on the specified port. 42 * 43 * If the server returned fails to bind to the specified port when serve() is 44 * called on it, createServer() may be called again on a different port. 45 */ 46 virtual std::shared_ptr<server::TServer> createServer(uint16_t port) = 0; 47 48 /** 49 * Get the TServerEventHandler to set on the server. 50 * 51 * This is only called after the server successfully binds and is about to 52 * start serving traffic. It is invoked from the server thread, rather than 53 * the main thread. 54 */ getServerEventHandler()55 virtual std::shared_ptr<server::TServerEventHandler> getServerEventHandler() { 56 return std::shared_ptr<server::TServerEventHandler>(); 57 } 58 59 /** 60 * This method is called in the server thread after server binding succeeds. 61 * 62 * Subclasses may override this method if they wish to record the final 63 * port that was used for the server. 64 */ bindSuccessful(uint16_t)65 virtual void bindSuccessful(uint16_t /*port*/) {} 66 }; 67 68 /** 69 * ServerThread starts a thrift server running in a separate thread. 70 */ 71 class ServerThread { 72 public: ServerThread(const std::shared_ptr<ServerState> & state,bool autoStart)73 ServerThread(const std::shared_ptr<ServerState>& state, bool autoStart) 74 : port_(0), 75 running_(false), 76 serving_(false), 77 error_(false), 78 serverState_(state) { 79 if (autoStart) { 80 start(); 81 } 82 } 83 84 void start(); 85 void stop(); 86 getPort()87 uint16_t getPort() const { return port_; } 88 ~ServerThread()89 ~ServerThread() { 90 if (running_) { 91 try { 92 stop(); 93 } catch (...) { 94 GlobalOutput.printf("error shutting down server"); 95 } 96 } 97 } 98 99 protected: 100 // Annoying. thrift forces us to use shared_ptr, so we have to use 101 // a helper class that we can allocate on the heap and give to thrift. 102 // It would be simpler if we could just make Runnable and TServerEventHandler 103 // private base classes of ServerThread. 104 class Helper : public concurrency::Runnable, public server::TServerEventHandler { 105 public: Helper(ServerThread * serverThread)106 Helper(ServerThread* serverThread) : serverThread_(serverThread) {} 107 run()108 void run() override { serverThread_->run(); } 109 preServe()110 void preServe() override { serverThread_->preServe(); } 111 112 private: 113 ServerThread* serverThread_; 114 }; 115 116 void run(); 117 void preServe(); 118 119 std::shared_ptr<Helper> helper_; 120 121 uint16_t port_; 122 bool running_; 123 bool serving_; 124 bool error_; 125 concurrency::Monitor serverMonitor_; 126 127 std::shared_ptr<ServerState> serverState_; 128 std::shared_ptr<server::TServer> server_; 129 std::shared_ptr<concurrency::Thread> thread_; 130 }; 131 } 132 } 133 } // apache::thrift::test 134 135 #endif // _THRIFT_TEST_SERVERTHREAD_H_ 136