Browse Source

[trac388] add stop server interface into dns server

hanfeng 14 years ago
parent
commit
6df94e2db8

+ 3 - 0
src/lib/asiolink/dns_server.h

@@ -75,6 +75,9 @@ public:
         (*self_)(ec, length);
     }
 
+    /// \brief Stop current running server 
+    virtual void stop() { self_->stop();}
+
     /// \brief Resume processing of the server coroutine after an 
     /// asynchronous call (e.g., to the DNS Lookup provider) has completed.
     ///

+ 13 - 1
src/lib/asiolink/tcp_server.cc

@@ -46,7 +46,7 @@ TCPServer::TCPServer(io_service& io_service,
                      const SimpleCallback* checkin,
                      const DNSLookup* lookup,
                      const DNSAnswer* answer) :
-    io_(io_service), done_(false),
+    io_(io_service), done_(false), stopped_by_hand_(false),
     checkin_callback_(checkin), lookup_callback_(lookup),
     answer_callback_(answer)
 {
@@ -68,6 +68,13 @@ TCPServer::operator()(error_code ec, size_t length) {
     /// Because the coroutine reeentry block is implemented as
     /// a switch statement, inline variable declarations are not
     /// permitted.  Certain variables used below can be declared here.
+    
+    /// If user has stopped the server, we won't enter the
+    /// coroutine body, just return 
+    if (stopped_by_hand_) {
+        return;
+    }
+
     boost::array<const_buffer,2> bufs;
     OutputBuffer lenbuf(TCP_MESSAGE_LENGTHSIZE);
 
@@ -181,6 +188,11 @@ TCPServer::asyncLookup() {
                         answer_message_, respbuf_, this);
 }
 
+void TCPServer::stop() {
+    stopped_by_hand_ = true;
+    acceptor_->close();
+    socket_->close();
+}
 /// Post this coroutine on the ASIO service queue so that it will
 /// resume processing where it left off.  The 'done' parameter indicates
 /// whether there is an answer to return to the client.

+ 4 - 0
src/lib/asiolink/tcp_server.h

@@ -43,6 +43,7 @@ public:
     void operator()(asio::error_code ec = asio::error_code(),
                     size_t length = 0);
     void asyncLookup();
+    void stop();
     void resume(const bool done);
     bool hasAnswer() { return (done_); }
     int value() { return (get_value()); }
@@ -106,6 +107,9 @@ private:
     size_t bytes_;
     bool done_;
 
+    // whether user has stopped the server
+    bool stopped_by_hand_;
+
     // Callback functions provided by the caller
     const SimpleCallback* checkin_callback_;
     const DNSLookup* lookup_callback_;

+ 20 - 2
src/lib/asiolink/udp_server.cc

@@ -54,8 +54,9 @@ struct UDPServer::Data {
      */
     Data(io_service& io_service, const ip::address& addr, const uint16_t port,
         SimpleCallback* checkin, DNSLookup* lookup, DNSAnswer* answer) :
-        io_(io_service), done_(false), checkin_callback_(checkin),
-        lookup_callback_(lookup), answer_callback_(answer)
+        io_(io_service), done_(false), stopped_by_hand_(false),
+        checkin_callback_(checkin),lookup_callback_(lookup),
+        answer_callback_(answer)
     {
         // We must use different instantiations for v4 and v6;
         // otherwise ASIO will bind to both
@@ -77,6 +78,7 @@ struct UDPServer::Data {
      */
     Data(const Data& other) :
         io_(other.io_), socket_(other.socket_), done_(false),
+        stopped_by_hand_(false),
         checkin_callback_(other.checkin_callback_),
         lookup_callback_(other.lookup_callback_),
         answer_callback_(other.answer_callback_)
@@ -140,6 +142,9 @@ struct UDPServer::Data {
     size_t bytes_;
     bool done_;
 
+    //whether user implicitly stop the server
+    bool stopped_by_hand_;
+
     // Callback functions provided by the caller
     const SimpleCallback* checkin_callback_;
     const DNSLookup* lookup_callback_;
@@ -167,6 +172,12 @@ UDPServer::operator()(error_code ec, size_t length) {
     /// a switch statement, inline variable declarations are not
     /// permitted.  Certain variables used below can be declared here.
 
+    /// if user stopped the server, we won't enter the coroutine body
+    /// just return
+    if (data_->stopped_by_hand_) {
+        return;
+    }
+
     CORO_REENTER (this) {
         do {
             /*
@@ -267,6 +278,13 @@ UDPServer::asyncLookup() {
         data_->query_message_, data_->answer_message_, data_->respbuf_, this);
 }
 
+/// Stop the UDPServer
+void
+UDPServer::stop() {
+    data_->stopped_by_hand_ = true;
+    data_->socket_->close();
+}
+
 /// Post this coroutine on the ASIO service queue so that it will
 /// resume processing where it left off.  The 'done' parameter indicates
 /// whether there is an answer to return to the client.

+ 4 - 0
src/lib/asiolink/udp_server.h

@@ -58,6 +58,10 @@ public:
     /// \brief Calls the lookup callback
     void asyncLookup();
 
+    /// \brief Stop the running server
+    /// \note once the server stopped, it can't restart
+    void stop();
+
     /// \brief Resume operation
     ///
     /// \param done Set this to true if the lookup action is done and