Skip to content

Commit 1c300b4

Browse files
committed
oak: Replace Boost shared_mutex, filesystem::path with std classes
This means we no longer need Boost for this library at all.
1 parent 42a42ec commit 1c300b4

File tree

6 files changed

+38
-33
lines changed

6 files changed

+38
-33
lines changed

oak/CMakeLists.txt

+1-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ set(alias cloe::oak)
1111

1212
find_package(cloe-runtime REQUIRED)
1313
find_package(oatpp REQUIRED)
14-
find_package(Boost COMPONENTS headers REQUIRED)
1514

1615
file(GLOB ${target}_PUBLIC_HEADERS "include/**/*.hpp")
1716
add_library(${target}
@@ -41,7 +40,7 @@ target_link_libraries(${target}
4140
PUBLIC
4241
cloe::runtime
4342
oatpp::oatpp
44-
Boost::headers
43+
stdc++fs
4544
)
4645

4746
# Testing ------------------------------------------------------------
@@ -66,7 +65,6 @@ if(BUILD_TESTING)
6665
target_link_libraries(test-oak
6766
GTest::gtest
6867
GTest::gtest_main
69-
Boost::boost
7068
${target}
7169
)
7270
gtest_add_tests(TARGET test-oak)

oak/conanfile.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ def package(self):
6868
cm.install()
6969

7070
def package_id(self):
71-
self.info.requires["boost"].full_package_mode()
7271
del self.info.options.pedantic
7372

7473
def package_info(self):
@@ -77,6 +76,13 @@ def package_info(self):
7776
self.cpp_info.set_property("cmake_target_name", "cloe::oak")
7877
self.cpp_info.set_property("pkg_config_name", "cloe-oak")
7978

79+
# Linking to libstdc++fs is required on GCC < 9.
80+
# (GCC compilers with version < 7 have no std::filesystem support.)
81+
# No consideration has been made yet for other compilers,
82+
# please add them here as necessary.
83+
if self.settings.get_safe("compiler") == "gcc" and self.settings.get_safe("compiler.version") in ["7", "8"]:
84+
self.cpp_info.system_libs = ["stdc++fs"]
85+
8086
# Make sure we can find the library, both in editable mode and in the
8187
# normal package mode:
8288
if not self.in_local_cache:

oak/include/oak/registrar.hpp

+5-7
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,10 @@
2525
#include <functional>
2626
#include <initializer_list>
2727
#include <map>
28+
#include <mutex>
2829
#include <string>
2930
#include <utility>
3031

31-
#include <boost/thread/locks.hpp> // for unique_lock
32-
#include <boost/thread/shared_mutex.hpp> // for shared_mutex
33-
3432
#include <cloe/handler.hpp> // for Handler
3533

3634
#include "oak/route_muxer.hpp" // for Muxer
@@ -194,12 +192,12 @@ class LockedRegistrar : public StaticRegistrar {
194192
*
195193
* On destruction, the lock is released.
196194
*/
197-
boost::unique_lock<boost::shared_mutex> lock() {
198-
return boost::unique_lock<boost::shared_mutex>(access_);
195+
std::unique_lock<std::shared_mutex> lock() {
196+
return std::unique_lock(access_);
199197
}
200198

201199
private:
202-
mutable boost::shared_mutex access_;
200+
mutable std::shared_mutex access_;
203201
};
204202

205203
/**
@@ -248,7 +246,7 @@ class BufferRegistrar : public StaticRegistrar {
248246
void refresh_route(const std::string& key);
249247

250248
protected:
251-
mutable boost::shared_mutex access_;
249+
mutable std::shared_mutex access_;
252250
Muxer<Response> buffer_;
253251
Muxer<Handler> handlers_;
254252
};

oak/include/oak/route_muxer.hpp

+19-18
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,15 @@
2323
#pragma once
2424

2525
#include <algorithm>
26+
#include <filesystem>
2627
#include <map>
28+
#include <mutex>
29+
#include <shared_mutex>
2730
#include <stdexcept>
2831
#include <string>
2932
#include <utility>
3033
#include <vector>
3134

32-
#include <boost/algorithm/string/predicate.hpp>
33-
#include <boost/filesystem/path.hpp>
34-
#include <boost/thread/locks.hpp>
35-
#include <boost/thread/shared_mutex.hpp>
36-
3735
namespace oak {
3836

3937
using Parameters = std::map<std::string, std::string>;
@@ -76,11 +74,11 @@ class Muxer {
7674
*/
7775
static std::string normalize(const std::string& route) {
7876
std::string s = route.substr(0, route.find("?"));
79-
boost::filesystem::path p(s);
77+
std::filesystem::path p(s);
8078
if (!p.is_absolute()) {
8179
return "";
8280
}
83-
s = p.normalize().string();
81+
s = p.lexically_normal().string();
8482
s = s.substr(0, s.find_last_not_of("/. \n\t\r") + 1);
8583
if (s.empty()) {
8684
return "/";
@@ -109,15 +107,18 @@ class Muxer {
109107
*/
110108
std::string resolve(const std::string& route) const {
111109
auto key = normalize(route);
112-
boost::shared_lock<boost::shared_mutex> read_lock(access_);
110+
std::shared_lock read_lock(access_);
113111
if (!backtrack_) {
114112
if (routes_.count(key)) {
115113
return key;
116114
}
117115
return "";
118116
} else {
119-
boost::filesystem::path p(key);
117+
std::filesystem::path p(key);
120118
while (!routes_.count(p.string())) {
119+
if (p.string() == "/") {
120+
return "";
121+
}
121122
p = p.parent_path();
122123
}
123124
return p.string();
@@ -128,7 +129,7 @@ class Muxer {
128129
* Set the backtracking behavior.
129130
*/
130131
void set_backtrack(bool enabled) {
131-
boost::unique_lock<boost::shared_mutex> write_lock(access_);
132+
std::unique_lock write_lock(access_);
132133
backtrack_ = enabled;
133134
}
134135

@@ -139,7 +140,7 @@ class Muxer {
139140

140141
std::vector<std::string> routes() const {
141142
std::vector<std::string> vs;
142-
boost::shared_lock<boost::shared_mutex> read_lock(access_);
143+
std::shared_lock read_lock(access_);
143144
for (const auto& kv : routes_) {
144145
if (kv.first.empty()) {
145146
continue;
@@ -151,13 +152,13 @@ class Muxer {
151152

152153
bool has(const std::string& route) const {
153154
auto key = normalize(route);
154-
boost::shared_lock<boost::shared_mutex> read_lock(access_);
155+
std::shared_lock read_lock(access_);
155156
return routes_.count(key) != 0;
156157
}
157158

158159
void add(const std::string& route, T val) {
159160
auto key = normalize(route);
160-
boost::unique_lock<boost::shared_mutex> write_lock(access_);
161+
std::unique_lock write_lock(access_);
161162
if (routes_.count(key)) {
162163
throw std::runtime_error("route already exists");
163164
}
@@ -166,7 +167,7 @@ class Muxer {
166167

167168
void set(const std::string& route, T val) {
168169
auto key = normalize(route);
169-
boost::unique_lock<boost::shared_mutex> write_lock(access_);
170+
std::unique_lock write_lock(access_);
170171
routes_[key] = val;
171172
}
172173

@@ -179,18 +180,18 @@ class Muxer {
179180
std::pair<T, Parameters> get(const std::string& route) const {
180181
auto key = resolve(route);
181182
Parameters p{};
182-
boost::shared_lock<boost::shared_mutex> read_lock(access_);
183+
std::shared_lock read_lock(access_);
183184
return std::make_pair(routes_.at(key), p);
184185
}
185186

186187
void set_unsafe(const std::string& key, T val) {
187-
boost::unique_lock<boost::shared_mutex> write_lock(access_);
188+
std::unique_lock write_lock(access_);
188189
routes_[key] = val;
189190
}
190191

191192
std::pair<T, Parameters> get_unsafe(const std::string& key) const {
192193
Parameters p{};
193-
boost::shared_lock<boost::shared_mutex> read_lock(access_);
194+
std::shared_lock read_lock(access_);
194195
return std::make_pair(routes_.at(key), p);
195196
}
196197

@@ -200,7 +201,7 @@ class Muxer {
200201

201202
// State:
202203
std::map<std::string, T> routes_;
203-
mutable boost::shared_mutex access_;
204+
mutable std::shared_mutex access_;
204205
};
205206

206207
} // namespace oak

oak/src/oak/registrar.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "oak/registrar.hpp"
2424

2525
#include <map>
26+
#include <mutex>
27+
#include <shared_mutex>
2628
#include <memory>
2729
#include <string>
2830

@@ -93,7 +95,7 @@ void LockedRegistrar::register_handler(const std::string& route, Handler h) {
9395
assert(route.size() != 0 && route[0] == '/');
9496
assert(proxy_ == nullptr);
9597
h = [this, h](const cloe::Request& q, Response& r) {
96-
boost::shared_lock<boost::shared_mutex> read_lock(this->access_);
98+
std::shared_lock read_lock(this->access_);
9799
h(q, r);
98100
};
99101

@@ -117,13 +119,13 @@ void BufferRegistrar::register_handler(const std::string& route, Handler h) {
117119
server_->add_handler(key, [this, key](const cloe::Request&, Response& r) {
118120
// Technically it's not necessary to lock, but when we are updating the
119121
// buffers, we do not want any requests to get through.
120-
boost::shared_lock<boost::shared_mutex> read_lock(this->access_);
122+
std::shared_lock read_lock(this->access_);
121123
r = this->buffer_.get(key).first;
122124
});
123125
}
124126

125127
void BufferRegistrar::refresh_buffer() {
126-
boost::unique_lock<boost::shared_mutex> write_lock(access_);
128+
std::unique_lock write_lock(access_);
127129
// We don't delete handlers, so there will never be routes
128130
// that are in handlers_ but not in buffer_.
129131
for (auto key : handlers_.routes()) {

oak/src/oak/route_muxer_test.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ TEST(oak_muxer, normalize) {
4343
{"/abc?", "/abc"},
4444
{"/abc/?opt=/next", "/abc"},
4545
{"C:", ""},
46-
{"//", ""},
46+
{"//", "/"},
4747
{"/..", "/"},
4848
{"/abc//.", "/abc"},
4949
{"/index.html", "/index.html"},

0 commit comments

Comments
 (0)