Skip to content

Commit c6a6530

Browse files
authored
Merge pull request yhirose#53 from yhirose/issue-52
Issue 52
2 parents 66550eb + 9dc4e23 commit c6a6530

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

httplib.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ typedef int socket_t;
5252
#include <functional>
5353
#include <map>
5454
#include <memory>
55+
#include <mutex>
5556
#include <regex>
5657
#include <string>
5758
#include <thread>
@@ -204,6 +205,8 @@ class Server {
204205
bool is_running() const;
205206
void stop();
206207

208+
bool is_handling_requests() const;
209+
207210
protected:
208211
bool process_request(Stream& strm, bool last_connection);
209212

@@ -231,6 +234,10 @@ class Server {
231234
Handlers post_handlers_;
232235
Handler error_handler_;
233236
Logger logger_;
237+
238+
// TODO: Use thread pool...
239+
std::mutex running_threads_mutex_;
240+
int running_threads_;
234241
};
235242

236243
class Client {
@@ -1407,6 +1414,7 @@ inline std::string SocketStream::get_remote_addr() {
14071414
inline Server::Server(HttpVersion http_version)
14081415
: http_version_(http_version)
14091416
, svr_sock_(-1)
1417+
, running_threads_(0)
14101418
{
14111419
#ifndef _WIN32
14121420
signal(SIGPIPE, SIG_IGN);
@@ -1476,6 +1484,11 @@ inline void Server::stop()
14761484
svr_sock_ = -1;
14771485
}
14781486

1487+
inline bool Server::is_handling_requests() const
1488+
{
1489+
return running_threads_ > 0;
1490+
}
1491+
14791492
inline bool Server::parse_request_line(const char* s, Request& req)
14801493
{
14811494
static std::regex re("(GET|HEAD|POST) ([^?]+)(?:\\?(.+?))? (HTTP/1\\.[01])\r\n");
@@ -1632,10 +1645,29 @@ inline bool Server::listen_internal()
16321645

16331646
// TODO: Use thread pool...
16341647
std::thread([=]() {
1648+
{
1649+
std::lock_guard<std::mutex> guard(running_threads_mutex_);
1650+
running_threads_++;
1651+
}
1652+
16351653
read_and_close_socket(sock);
1654+
1655+
{
1656+
std::lock_guard<std::mutex> guard(running_threads_mutex_);
1657+
running_threads_--;
1658+
}
16361659
}).detach();
16371660
}
16381661

1662+
// TODO: Use thread pool...
1663+
for (;;) {
1664+
std::this_thread::sleep_for(std::chrono::milliseconds(10));
1665+
std::lock_guard<std::mutex> guard(running_threads_mutex_);
1666+
if (!running_threads_) {
1667+
break;
1668+
}
1669+
}
1670+
16391671
return ret;
16401672
}
16411673

test/test.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ class ServerTest : public ::testing::Test {
262262
svr_.get("/hi", [&](const Request& /*req*/, Response& res) {
263263
res.set_content("Hello World!", "text/plain");
264264
})
265+
.get("/slow", [&](const Request& /*req*/, Response& res) {
266+
msleep(3000);
267+
res.set_content("slow", "text/plain");
268+
})
265269
.get("/remote_addr", [&](const Request& req, Response& res) {
266270
auto remote_addr = req.headers.find("REMOTE_ADDR")->second;
267271
res.set_content(remote_addr.c_str(), "text/plain");
@@ -358,6 +362,7 @@ class ServerTest : public ::testing::Test {
358362
virtual void TearDown() {
359363
svr_.stop();
360364
t_.join();
365+
EXPECT_EQ(false, svr_.is_handling_requests());
361366
}
362367

363368
map<string, string> persons_;
@@ -664,6 +669,14 @@ TEST_F(ServerTest, GetMethodRemoteAddr)
664669
EXPECT_TRUE(res->body == "::1" || res->body == "127.0.0.1");
665670
}
666671

672+
TEST_F(ServerTest, SlowRequest)
673+
{
674+
std::thread([=]() { auto res = cli_.get("/slow"); }).detach();
675+
std::thread([=]() { auto res = cli_.get("/slow"); }).detach();
676+
std::thread([=]() { auto res = cli_.get("/slow"); }).detach();
677+
msleep(1000);
678+
}
679+
667680
#ifdef CPPHTTPLIB_ZLIB_SUPPORT
668681
TEST_F(ServerTest, Gzip)
669682
{

0 commit comments

Comments
 (0)