yhirose 7 years ago
parent
commit
b6df220b55
2 changed files with 47 additions and 9 deletions
  1. 13 9
      httplib.h
  2. 34 0
      test/test.cc

+ 13 - 9
httplib.h

@@ -230,6 +230,7 @@ private:
 
 
     virtual bool read_and_close_socket(socket_t sock);
     virtual bool read_and_close_socket(socket_t sock);
 
 
+    bool        is_running_;
     socket_t    svr_sock_;
     socket_t    svr_sock_;
     std::string base_dir_;
     std::string base_dir_;
     Handlers    get_handlers_;
     Handlers    get_handlers_;
@@ -1415,6 +1416,7 @@ inline std::string SocketStream::get_remote_addr() {
 // HTTP server implementation
 // HTTP server implementation
 inline Server::Server(HttpVersion http_version)
 inline Server::Server(HttpVersion http_version)
     : http_version_(http_version)
     : http_version_(http_version)
+    , is_running_(false)
     , svr_sock_(-1)
     , svr_sock_(-1)
     , running_threads_(0)
     , running_threads_(0)
 {
 {
@@ -1476,19 +1478,17 @@ inline bool Server::listen(const char* host, int port, int socket_flags)
 
 
 inline bool Server::is_running() const
 inline bool Server::is_running() const
 {
 {
-    return svr_sock_ != -1;
+    return is_running_;
 }
 }
 
 
 inline void Server::stop()
 inline void Server::stop()
 {
 {
-    detail::shutdown_socket(svr_sock_);
-    detail::close_socket(svr_sock_);
-    svr_sock_ = -1;
-}
-
-inline bool Server::is_handling_requests() const
-{
-    return running_threads_ > 0;
+    if (is_running_) {
+        assert(svr_sock_ != -1);
+        detail::shutdown_socket(svr_sock_);
+        detail::close_socket(svr_sock_);
+        svr_sock_ = -1;
+    }
 }
 }
 
 
 inline bool Server::parse_request_line(const char* s, Request& req)
 inline bool Server::parse_request_line(const char* s, Request& req)
@@ -1622,6 +1622,8 @@ inline bool Server::listen_internal()
 {
 {
     auto ret = true;
     auto ret = true;
 
 
+    is_running_ = true;
+
     for (;;) {
     for (;;) {
         auto val = detail::select_read(svr_sock_, 0, 100000);
         auto val = detail::select_read(svr_sock_, 0, 100000);
 
 
@@ -1670,6 +1672,8 @@ inline bool Server::listen_internal()
         }
         }
     }
     }
 
 
+    is_running_ = false;
+
     return ret;
     return ret;
 }
 }
 
 

+ 34 - 0
test/test.cc

@@ -835,6 +835,40 @@ TEST_F(ServerTestWithAI_PASSIVE, GetMethod200)
     EXPECT_EQ("Hello World!", res->body);
     EXPECT_EQ("Hello World!", res->body);
 }
 }
 
 
+class ServerUpDownTest : public ::testing::Test {
+protected:
+    ServerUpDownTest()
+        : cli_(HOST, PORT)
+        {}
+
+    virtual void SetUp() {
+        t_ = thread([&](){
+            svr_.bind_to_any_port(HOST);
+            msleep(500);
+            svr_.listen_after_bind();
+        });
+
+        while (!svr_.is_running()) {
+            msleep(1);
+        }
+    }
+
+    virtual void TearDown() {
+        svr_.stop();
+        t_.join();
+    }
+
+    Client              cli_;
+    Server              svr_;
+    thread              t_;
+};
+
+TEST_F(ServerUpDownTest, QuickStartStop)
+{
+    // Should not crash, especially when run with
+    // --gtest_filter=ServerUpDownTest.QuickStartStop --gtest_repeat=1000
+}
+
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 TEST(SSLClientTest, ServerNameIndication)
 TEST(SSLClientTest, ServerNameIndication)
 {
 {