Skip to content

Commit 5fbc670

Browse files
committed
Make session management thread-safe.
1 parent 62897e0 commit 5fbc670

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

http/src/http/server/simple_sessions.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,24 @@
55
// http://www.boost.org/LICENSE_1_0.txt)
66

77
#include <http/server/simple_sessions.hpp>
8+
#include <cassert>
89

910
namespace network {
1011
namespace http {
1112

1213
session& simple_sessions::lookup(boost::string_ref session_id) {
13-
std::string real_session_id = session_id.empty() ?
14-
std::to_string(next_session_id_.fetch_add(1, std::memory_order::memory_order_seq_cst))
15-
: static_cast<std::string>(session_id);
14+
std::string real_session_id =
15+
session_id.empty() ? std::to_string(next_session_id_.fetch_add(
16+
1, std::memory_order::memory_order_seq_cst)) :
17+
static_cast<std::string>(session_id);
18+
assert(real_session_id != "");
19+
std::lock_guard<std::mutex> lock_sessions(sessions_mutex_);
1620
std::pair<session_map_type::iterator, bool> result =
1721
sessions_.insert(make_pair(std::move(real_session_id), session()));
18-
result.first->second.set("id", real_session_id);
22+
if (result.second) {
23+
result.first->second.set("id", result.first->first);
24+
assert(result.first->second["id"] != "");
25+
}
1926
return result.first->second;
2027
}
2128

http/src/http/server/simple_sessions.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <http/server/session.hpp>
1212
#include <boost/utility/string_ref.hpp>
1313
#include <atomic>
14+
#include <thread>
1415

1516
namespace network {
1617
namespace http {
@@ -25,6 +26,7 @@ struct simple_sessions {
2526
session &lookup(boost::string_ref session_id);
2627
private:
2728
typedef std::unordered_map<std::string, session> session_map_type;
29+
std::mutex sessions_mutex_;
2830
session_map_type sessions_;
2931
std::atomic_uint_fast64_t next_session_id_;
3032
};

http/test/server_simple_sessions_test.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <gtest/gtest.h>
88
#include <http/server/simple_sessions.hpp>
9+
#include <future>
910

1011
namespace http = network::http;
1112
namespace net = network;
@@ -35,4 +36,26 @@ TEST(simple_sessions_test, update) {
3536
}
3637
}
3738

39+
TEST(simple_sessions_test, threaded_sessions) {
40+
http::simple_sessions simple_sessions;
41+
auto f0 = std::async([&]() {
42+
http::session &session = simple_sessions.lookup("");
43+
return session["id"];
44+
});
45+
auto f1 = std::async([&]() {
46+
http::session &session = simple_sessions.lookup("");
47+
return session["id"];
48+
});
49+
auto f2 = std::async([&]() {
50+
http::session &session = simple_sessions.lookup("");
51+
return session["id"];
52+
});
53+
std::string session0 = f0.get(),
54+
session1 = f1.get(),
55+
session2 = f2.get();
56+
EXPECT_NE(session0, session1);
57+
EXPECT_NE(session1, session2);
58+
EXPECT_NE(session0, session2);
59+
}
60+
3861
} // namespace

0 commit comments

Comments
 (0)