aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authoripknHama <ipknhama@gmail.com>2015-02-20 13:44:46 +0900
committeripknHama <ipknhama@gmail.com>2015-02-20 13:44:46 +0900
commit48811ce4a47200567796730d7467526683f265d7 (patch)
treef54890849a58160c39fc67073316c1349463d4f6 /include
parent5507e98ce25f8468e37652b58a3512f40869af99 (diff)
downloadcrow-48811ce4a47200567796730d7467526683f265d7.tar.gz
crow-48811ce4a47200567796730d7467526683f265d7.zip
remove thread_local variables
* move thread_local variables forget_cached_date_str, timer_queue into each threads local stack
Diffstat (limited to 'include')
-rw-r--r--include/crow.h2
-rw-r--r--include/datetime.h77
-rw-r--r--include/dumb_timer_queue.h10
-rw-r--r--include/http_connection.h29
-rw-r--r--include/http_server.h54
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_;