diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/crow.h | 2 | ||||
-rw-r--r-- | include/datetime.h | 77 | ||||
-rw-r--r-- | include/dumb_timer_queue.h | 10 | ||||
-rw-r--r-- | include/http_connection.h | 29 | ||||
-rw-r--r-- | include/http_server.h | 54 |
5 files changed, 62 insertions, 110 deletions
diff --git a/include/crow.h b/include/crow.h index 953d990..cb9f1b3 100644 --- a/include/crow.h +++ b/include/crow.h @@ -10,11 +10,11 @@ #include "settings.h" #include "logging.h" -#include "http_server.h" #include "utility.h" #include "routing.h" #include "middleware_context.h" #include "http_request.h" +#include "http_server.h" #define CROW_ROUTE(app, url) app.route<crow::black_magic::get_parameter_tag(url)>(url) diff --git a/include/datetime.h b/include/datetime.h deleted file mode 100644 index 0a47379..0000000 --- a/include/datetime.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -#include <string> -#include <boost/date_time/local_time/local_time.hpp> -#include <boost/filesystem.hpp> - -namespace crow -{ - // code from http://stackoverflow.com/questions/2838524/use-boost-date-time-to-parse-and-create-http-dates - class DateTime - { - public: - DateTime() - : m_dt(boost::local_time::local_sec_clock::local_time(boost::local_time::time_zone_ptr())) - { - } - DateTime(const std::string& path) - : DateTime() - { - from_file(path); - } - - // return datetime string - std::string str() - { - static const std::locale locale_(std::locale::classic(), new boost::local_time::local_time_facet("%a, %d %b %Y %H:%M:%S GMT") ); - std::string result; - try - { - std::stringstream ss; - ss.imbue(locale_); - ss << m_dt; - result = ss.str(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << std::endl; - } - return result; - } - - // update datetime from file mod date - std::string from_file(const std::string& path) - { - try - { - boost::filesystem::path p(path); - boost::posix_time::ptime pt = boost::posix_time::from_time_t( - boost::filesystem::last_write_time(p)); - m_dt = boost::local_time::local_date_time(pt, boost::local_time::time_zone_ptr()); - } - catch (std::exception& e) - { - std::cout << "Exception: " << e.what() << std::endl; - } - return str(); - } - - // parse datetime string - void parse(const std::string& dt) - { - static const std::locale locale_(std::locale::classic(), new boost::local_time::local_time_facet("%a, %d %b %Y %H:%M:%S GMT") ); - std::stringstream ss(dt); - ss.imbue(locale_); - ss >> m_dt; - } - - // boolean equal operator - friend bool operator==(const DateTime& left, const DateTime& right) - { - return (left.m_dt == right.m_dt); - } - - private: - boost::local_time::local_date_time m_dt; - }; -} diff --git a/include/dumb_timer_queue.h b/include/dumb_timer_queue.h index 88bb661..6b690bb 100644 --- a/include/dumb_timer_queue.h +++ b/include/dumb_timer_queue.h @@ -16,13 +16,6 @@ namespace crow class dumb_timer_queue { public: - // tls based queue to avoid locking - static dumb_timer_queue& get_current_dumb_timer_queue() - { - thread_local dumb_timer_queue q; - return q; - } - using key = std::pair<dumb_timer_queue*, int>; void cancel(key& k) @@ -73,11 +66,12 @@ namespace crow io_service_ = &io_service; } - private: dumb_timer_queue() noexcept { } + private: + int tick{5}; boost::asio::io_service* io_service_{}; std::deque<std::pair<decltype(std::chrono::steady_clock::now()), std::function<void()>>> dq_; diff --git a/include/http_connection.h b/include/http_connection.h index d9ccb21..b1157a9 100644 --- a/include/http_connection.h +++ b/include/http_connection.h @@ -9,7 +9,6 @@ #include "http_parser_merged.h" -#include "datetime.h" #include "parser.h" #include "http_response.h" #include "logging.h" @@ -185,13 +184,17 @@ namespace crow boost::asio::io_service& io_service, Handler* handler, const std::string& server_name, - std::tuple<Middlewares...>* middlewares + std::tuple<Middlewares...>* middlewares, + std::function<std::string()>& get_cached_date_str_f, + detail::dumb_timer_queue& timer_queue ) : socket_(io_service), handler_(handler), parser_(this), server_name_(server_name), - middlewares_(middlewares) + middlewares_(middlewares), + get_cached_date_str(get_cached_date_str_f), + timer_queue(timer_queue) { #ifdef CROW_ENABLE_DEBUG connectionCount ++; @@ -426,20 +429,6 @@ namespace crow } private: - static std::string get_cached_date_str() - { - using namespace std::chrono; - thread_local auto last = steady_clock::now(); - thread_local std::string date_str = DateTime().str(); - - if (steady_clock::now() - last >= seconds(1)) - { - last = steady_clock::now(); - date_str = DateTime().str(); - } - return date_str; - } - void do_read() { //auto self = this->shared_from_this(); @@ -517,12 +506,11 @@ namespace crow void cancel_deadline_timer() { CROW_LOG_DEBUG << this << " timer cancelled: " << timer_cancel_key_.first << ' ' << timer_cancel_key_.second; - detail::dumb_timer_queue::get_current_dumb_timer_queue().cancel(timer_cancel_key_); + timer_queue.cancel(timer_cancel_key_); } void start_deadline(int timeout = 5) { - auto& timer_queue = detail::dumb_timer_queue::get_current_dumb_timer_queue(); cancel_deadline_timer(); timer_cancel_key_ = timer_queue.add([this] @@ -565,6 +553,9 @@ namespace crow std::tuple<Middlewares...>* middlewares_; detail::context<Middlewares...> ctx_; + + std::function<std::string()>& get_cached_date_str; + detail::dumb_timer_queue& timer_queue; }; } diff --git a/include/http_server.h b/include/http_server.h index bd35ba1..e7d9f4f 100644 --- a/include/http_server.h +++ b/include/http_server.h @@ -10,7 +10,6 @@ #include <memory> #include "http_connection.h" -#include "datetime.h" #include "logging.h" #include "dumb_timer_queue.h" @@ -40,13 +39,46 @@ namespace crow 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; for(uint16_t i = 0; i < concurrency_; i ++) v.push_back( std::async(std::launch::async, [this, i]{ + + // 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; + +#ifdef _MSC_VER + gmtime_s(&my_tm, &last_time_t); +#else + 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); + }; + 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; + }; + // initializing timer queue - auto& timer_queue = detail::dumb_timer_queue::get_current_dumb_timer_queue(); + detail::dumb_timer_queue timer_queue; + timer_queue_pool_[i] = &timer_queue; timer_queue.set_io_service(*io_service_pool_[i]); boost::asio::deadline_timer timer(*io_service_pool_[i]); @@ -71,12 +103,18 @@ namespace crow stop(); }); + for (int i = 0; i < concurrency_; i++) + { + while (timer_queue_pool_[i] == nullptr) + std::this_thread::yield(); + } + do_accept(); - v.push_back(std::async(std::launch::async, [this]{ + std::thread([this]{ io_service_.run(); CROW_LOG_INFO << "Exiting."; - })); + }).join(); } void stop() @@ -98,7 +136,11 @@ namespace crow void do_accept() { - auto p = new Connection<Handler, Middlewares...>(pick_io_service(), handler_, server_name_, middlewares_); + asio::io_service& is = pick_io_service(); + auto p = new Connection<Handler, Middlewares...>( + is, handler_, server_name_, middlewares_, + get_cached_date_str_pool_[roundrobin_index_], *timer_queue_pool_[roundrobin_index_] + ); acceptor_.async_accept(p->socket(), [this, p](boost::system::error_code ec) { @@ -113,6 +155,8 @@ namespace crow private: 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_; tcp::acceptor acceptor_; boost::asio::signal_set signals_; |