Remove multithreaded code, and make crow use a single thread
Change-Id: I39e9ba84ab3464cf75b5bba82badb729525bf3b9
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
diff --git a/crow/include/crow/app.h b/crow/include/crow/app.h
index c43faf3..be5523e 100644
--- a/crow/include/crow/app.h
+++ b/crow/include/crow/app.h
@@ -69,18 +69,6 @@
return *this;
}
- self_t& multithreaded() {
- return concurrency(std::thread::hardware_concurrency());
- }
-
- self_t& concurrency(std::uint16_t concurrency) {
- if (concurrency < 1) {
- concurrency = 1;
- }
- concurrency_ = concurrency;
- return *this;
- }
-
void validate() { router_.validate(); }
void run() {
@@ -88,13 +76,11 @@
#ifdef CROW_ENABLE_SSL
if (use_ssl_) {
if (-1 == socket_) {
- ssl_server_ = std::move(
- std::make_unique<ssl_server_t>(this, bindaddr_, port_, &middlewares_,
- concurrency_, &ssl_context_, io_));
+ ssl_server_ = std::move(std::make_unique<ssl_server_t>(
+ this, bindaddr_, port_, &middlewares_, &ssl_context_, io_));
} else {
- ssl_server_ = std::move(
- std::make_unique<ssl_server_t>(this, socket_, &middlewares_,
- concurrency_, &ssl_context_, io_));
+ ssl_server_ = std::move(std::make_unique<ssl_server_t>(
+ this, socket_, &middlewares_, &ssl_context_, io_));
}
ssl_server_->set_tick_function(tick_interval_, tick_function_);
ssl_server_->run();
@@ -103,30 +89,17 @@
{
if (-1 == socket_) {
server_ = std::move(std::make_unique<server_t>(
- this, bindaddr_, port_, &middlewares_, concurrency_, nullptr, io_));
+ this, bindaddr_, port_, &middlewares_, nullptr, io_));
} else {
server_ = std::move(std::make_unique<server_t>(
- this, socket_, &middlewares_, concurrency_, nullptr, io_));
+ this, socket_, &middlewares_, nullptr, io_));
}
server_->set_tick_function(tick_interval_, tick_function_);
server_->run();
}
}
- void stop() {
-#ifdef CROW_ENABLE_SSL
- if (use_ssl_) {
- if (ssl_server_ != nullptr) {
- ssl_server_->stop();
- }
- } else
-#endif
- {
- if (server_ != nullptr) {
- server_->stop();
- }
- }
- }
+ void stop() { io_->stop(); }
void debug_print() {
CROW_LOG_DEBUG << "Routing:";
@@ -221,7 +194,6 @@
private:
std::shared_ptr<asio::io_service> io_;
uint16_t port_ = 80;
- uint16_t concurrency_ = 1;
std::string bindaddr_ = "::";
int socket_ = -1;
Router router_;
diff --git a/crow/include/crow/http_server.h b/crow/include/crow/http_server.h
index 387d4a4..e770195 100644
--- a/crow/include/crow/http_server.h
+++ b/crow/include/crow/http_server.h
@@ -26,7 +26,6 @@
public:
Server(Handler* handler, std::unique_ptr<tcp::acceptor>&& acceptor,
std::tuple<Middlewares...>* middlewares = nullptr,
- uint16_t concurrency = 1,
typename Adaptor::context* adaptor_ctx = nullptr,
std::shared_ptr<boost::asio::io_service> io =
std::make_shared<boost::asio::io_service>())
@@ -35,33 +34,30 @@
signals_(*io_service_, SIGINT, SIGTERM),
tick_timer_(*io_service_),
handler_(handler),
- concurrency_(concurrency),
middlewares_(middlewares),
adaptor_ctx_(adaptor_ctx) {}
Server(Handler* handler, const std::string& bindaddr, uint16_t port,
std::tuple<Middlewares...>* middlewares = nullptr,
- uint16_t concurrency = 1,
typename Adaptor::context* adaptor_ctx = nullptr,
std::shared_ptr<boost::asio::io_service> io =
std::make_shared<boost::asio::io_service>())
: Server(handler,
- std::make_unique<tcp::acceptor>(
- *io, tcp::endpoint(
- boost::asio::ip::address::from_string(bindaddr), port)),
- middlewares, concurrency, adaptor_ctx, io) {}
-
+ std::make_unique<tcp::acceptor>(
+ *io,
+ tcp::endpoint(
+ boost::asio::ip::address::from_string(bindaddr), port)),
+ middlewares, adaptor_ctx, io) {}
Server(Handler* handler, int existing_socket,
std::tuple<Middlewares...>* middlewares = nullptr,
- uint16_t concurrency = 1,
typename Adaptor::context* adaptor_ctx = nullptr,
std::shared_ptr<boost::asio::io_service> io =
std::make_shared<boost::asio::io_service>())
: Server(handler,
- std::make_unique<tcp::acceptor>(
- *io, boost::asio::ip::tcp::v6(), existing_socket),
- middlewares, concurrency, adaptor_ctx, io) {}
+ std::make_unique<tcp::acceptor>(*io, boost::asio::ip::tcp::v6(),
+ existing_socket),
+ middlewares, adaptor_ctx, io) {}
void set_tick_function(std::chrono::milliseconds d, std::function<void()> f) {
tick_interval_ = d;
@@ -80,81 +76,49 @@
});
}
- void run() {
- if (concurrency_ < 0) {
- concurrency_ = 1;
- }
-
- for (int i = 0; i < concurrency_; i++) {
- io_service_pool_.emplace_back(new boost::asio::io_service());
- }
- get_cached_date_str_pool_.resize(concurrency_);
- timer_queue_pool_.resize(concurrency_);
-
- std::vector<std::future<void>> v;
- std::atomic<int> init_count(0);
- for (uint16_t i = 0; i < concurrency_; i++) {
- v.push_back(std::async(std::launch::async, [this, i, &init_count] {
-
- // thread local date string get function
- auto last = std::chrono::steady_clock::now();
-
- std::string date_str;
- auto update_date_str = [&] {
- auto last_time_t = time(0);
- tm my_tm{};
+ void update_date_str() {
+ auto last_time_t = time(0);
+ tm my_tm{};
#ifdef _MSC_VER
- gmtime_s(&my_tm, &last_time_t);
+ gmtime_s(&my_tm, &last_time_t);
#else
- gmtime_r(&last_time_t, &my_tm);
+ gmtime_r(&last_time_t, &my_tm);
#endif
- date_str.resize(100);
- size_t date_str_sz =
- strftime(&date_str[0], 99, "%a, %d %b %Y %H:%M:%S GMT", &my_tm);
- date_str.resize(date_str_sz);
- };
+ date_str.resize(100);
+ size_t date_str_sz =
+ strftime(&date_str[0], 99, "%a, %d %b %Y %H:%M:%S GMT", &my_tm);
+ date_str.resize(date_str_sz);
+ };
+
+ void run() {
+ update_date_str();
+
+ get_cached_date_str_ = [this]() -> std::string {
+ static std::chrono::time_point<std::chrono::steady_clock>
+ last_date_update = std::chrono::steady_clock::now();
+ if (std::chrono::steady_clock::now() - last_date_update >=
+ std::chrono::seconds(10)) {
+ last_date_update = std::chrono::steady_clock::now();
update_date_str();
- get_cached_date_str_pool_[i] = [&]() -> std::string {
- if (std::chrono::steady_clock::now() - last >=
- std::chrono::seconds(1)) {
- last = std::chrono::steady_clock::now();
- update_date_str();
- }
- return date_str;
- };
+ }
+ return this->date_str;
+ };
- // initializing timer queue
- detail::dumb_timer_queue timer_queue;
- timer_queue_pool_[i] = &timer_queue;
+ timer_queue_.set_io_service(*io_service_);
+ boost::asio::deadline_timer timer(*io_service_);
+ timer.expires_from_now(boost::posix_time::seconds(1));
- timer_queue.set_io_service(*io_service_pool_[i]);
- boost::asio::deadline_timer timer(*io_service_pool_[i]);
- timer.expires_from_now(boost::posix_time::seconds(1));
-
- std::function<void(const boost::system::error_code& ec)> handler;
- handler = [&](const boost::system::error_code& ec) {
- if (ec != nullptr) {
- return;
- }
- timer_queue.process();
- timer.expires_from_now(boost::posix_time::seconds(1));
- timer.async_wait(handler);
- };
- timer.async_wait(handler);
- init_count++;
- for (;;) {
- try {
- io_service_pool_[i]->run();
- break;
- } catch (std::exception& e) {
- std::cerr << "Worker Crash: An uncaught exception occurred: "
- << e.what();
- } catch (...) {
- }
- }
- }));
- }
+ std::function<void(const boost::system::error_code& ec)> handler;
+ handler = [&](const boost::system::error_code& ec) {
+ if (ec != nullptr) {
+ return;
+ }
+ timer_queue_.process();
+ timer.expires_from_now(boost::posix_time::seconds(1));
+ timer.async_wait(handler);
+ };
+ timer.async_wait(handler);
if (tick_function_ && tick_interval_.count() > 0) {
tick_timer_.expires_from_now(
@@ -173,63 +137,38 @@
signals_.async_wait([&](const boost::system::error_code& /*error*/,
int /*signal_number*/) { stop(); });
- while (concurrency_ != init_count) {
- std::this_thread::yield();
- }
-
do_accept();
-
- io_service_->run();
- CROW_LOG_INFO << "Exiting.";
}
- void stop() {
- io_service_->stop();
- for (auto& io_service : io_service_pool_) {
- io_service->stop();
- }
- }
-
- private:
- asio::io_service& pick_io_service() {
- // TODO load balancing
- roundrobin_index_++;
- if (roundrobin_index_ >= io_service_pool_.size()) {
- roundrobin_index_ = 0;
- }
- return *io_service_pool_[roundrobin_index_];
- }
+ void stop() { io_service_->stop(); }
void do_accept() {
- asio::io_service& is = pick_io_service();
auto p = new Connection<Adaptor, Handler, Middlewares...>(
- is, handler_, server_name_, middlewares_,
- get_cached_date_str_pool_[roundrobin_index_],
- *timer_queue_pool_[roundrobin_index_], adaptor_ctx_);
+ *io_service_, handler_, server_name_, middlewares_,
+ get_cached_date_str_, timer_queue_, adaptor_ctx_);
acceptor_->async_accept(p->socket(),
- [this, p, &is](boost::system::error_code ec) {
- if (!ec) {
- is.post([p] { p->start(); });
- } else {
- delete p;
- }
- do_accept();
- });
+ [this, p](boost::system::error_code ec) {
+ if (!ec) {
+ this->io_service_->post([p] { p->start(); });
+ } else {
+ delete p;
+ }
+ do_accept();
+ });
}
private:
std::shared_ptr<asio::io_service> io_service_;
- std::vector<std::unique_ptr<asio::io_service>> io_service_pool_;
- std::vector<detail::dumb_timer_queue*> timer_queue_pool_;
- std::vector<std::function<std::string()>> get_cached_date_str_pool_;
+ detail::dumb_timer_queue timer_queue_;
+ std::function<std::string()> get_cached_date_str_;
std::unique_ptr<tcp::acceptor> acceptor_;
boost::asio::signal_set signals_;
boost::asio::deadline_timer tick_timer_;
+ std::string date_str;
+
Handler* handler_;
- uint16_t concurrency_{1};
std::string server_name_ = "iBMC";
- unsigned int roundrobin_index_{};
std::chrono::milliseconds tick_interval_{};
std::function<void()> tick_function_;
@@ -241,5 +180,5 @@
boost::asio::ssl::context ssl_context_{boost::asio::ssl::context::sslv23};
#endif
typename Adaptor::context* adaptor_ctx_;
-};
+}; // namespace crow
} // namespace crow
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 53dd127..b84c94c 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -1,3 +1,4 @@
+#include <systemd/sd-daemon.h>
#include <dbus/connection.hpp>
#include <dbus_monitor.hpp>
#include <dbus_singleton.hpp>
@@ -16,7 +17,6 @@
#include "webserver_common.hpp"
#include <crow/app.h>
#include <boost/asio.hpp>
-#include <systemd/sd-daemon.h>
constexpr int defaultPort = 18080;
@@ -31,7 +31,7 @@
app.socket(SD_LISTEN_FDS_START);
} else {
CROW_LOG_INFO << "bad incoming socket, starting webserver on port "
- << defaultPort;
+ << defaultPort;
app.port(defaultPort);
}
} else {
@@ -78,4 +78,5 @@
redfish::RedfishService redfish(app);
app.run();
+ io->run();
}