Skip to content

Commit 4c411e7

Browse files
committed
Swap support for request.
1 parent 84e46e6 commit 4c411e7

File tree

5 files changed

+41
-12
lines changed

5 files changed

+41
-12
lines changed

boost/network/protocol/http/request/request.ipp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ bool request::equals(request const &other) const {
144144

145145
void request::swap(request & other) {
146146
std::swap(this->pimpl_, other.pimpl_);
147+
request_storage_base::swap(other);
147148
}
148149

149150
// From message_base...

boost/network/protocol/http/request/request_base.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct request_storage_base {
3232
virtual void flatten(std::string &destination) const;
3333
virtual void clear();
3434
virtual bool equals(request_storage_base const &other) const;
35+
virtual void swap(request_storage_base &other);
3536
virtual ~request_storage_base();
3637

3738
private:

boost/network/protocol/http/request/request_base.ipp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ struct request_storage_base_pimpl {
2525
void flatten(std::string &destination) const;
2626
void clear();
2727
bool equals(request_storage_base_pimpl const &other) const;
28+
void swap(request_storage_base_pimpl &other);
2829
~request_storage_base_pimpl();
2930

3031
private:
3132
size_t chunk_size_;
3233
typedef std::vector<std::pair<char *, size_t> > chunks_vector;
3334
chunks_vector chunks_;
34-
mutex chunk_mutex;
35+
mutable mutex chunk_mutex_;
3536

3637
request_storage_base_pimpl(request_storage_base_pimpl const &other);
3738
};
@@ -68,6 +69,10 @@ bool request_storage_base::equals(request_storage_base const &other) const {
6869
return pimpl_->equals(*other.pimpl_);
6970
}
7071

72+
void request_storage_base::swap(request_storage_base &other) {
73+
return other.pimpl_->swap(*pimpl_);
74+
}
75+
7176
request_storage_base_pimpl::request_storage_base_pimpl(size_t chunk_size)
7277
: chunk_size_(chunk_size)
7378
, chunks_()
@@ -78,6 +83,7 @@ request_storage_base_pimpl::request_storage_base_pimpl(size_t chunk_size)
7883
request_storage_base_pimpl::request_storage_base_pimpl(request_storage_base_pimpl const &other)
7984
: chunk_size_(other.chunk_size_)
8085
, chunks_(0) {
86+
lock_guard<mutex> scoped_lock(other.chunk_mutex_);
8187
chunks_.reserve(other.chunks_.size());
8288
chunks_vector::const_iterator it = other.chunks_.begin();
8389
for (; it != other.chunks_.end(); ++it) {
@@ -95,6 +101,7 @@ request_storage_base_pimpl * request_storage_base_pimpl::clone() const {
95101
}
96102

97103
void request_storage_base_pimpl::append(char const *data, size_t size) {
104+
lock_guard<mutex> scoped_lock(chunk_mutex_);
98105
if (chunks_.empty()) {
99106
chunks_.push_back(std::make_pair(
100107
new (std::nothrow) char[chunk_size_], 0));
@@ -121,6 +128,7 @@ void request_storage_base_pimpl::append(char const *data, size_t size) {
121128
}
122129

123130
size_t request_storage_base_pimpl::read(char *destination, size_t offset, size_t size) const {
131+
lock_guard<mutex> scoped_lock(chunk_mutex_);
124132
if (chunks_.empty()) return 0;
125133
// First we find which chunk we're going to read from using the provided
126134
// offset and some arithmetic to determine the correct one.
@@ -145,13 +153,15 @@ size_t request_storage_base_pimpl::read(char *destination, size_t offset, size_t
145153
}
146154

147155
void request_storage_base_pimpl::flatten(std::string &destination) const {
156+
lock_guard<mutex> scpoped_lock(chunk_mutex_);
148157
chunks_vector::const_iterator chunk_iterator = chunks_.begin();
149158
for (; chunk_iterator != chunks_.end(); ++chunk_iterator) {
150159
destination.append(chunk_iterator->first, chunk_iterator->second);
151160
}
152161
}
153162

154163
void request_storage_base_pimpl::clear() {
164+
lock_guard<mutex> scoped_lock(chunk_mutex_);
155165
chunks_vector::const_iterator chunk_iterator = chunks_.begin();
156166
for (; chunk_iterator != chunks_.end(); ++chunk_iterator) {
157167
delete [] chunk_iterator->first;
@@ -160,18 +170,36 @@ void request_storage_base_pimpl::clear() {
160170
}
161171

162172
bool request_storage_base_pimpl::equals(request_storage_base_pimpl const &other) const {
163-
if (other.chunk_size_ != chunk_size_) return false;
164-
if (other.chunks_.size() != chunks_.size()) return false;
173+
lock(other.chunk_mutex_, this->chunk_mutex_);
174+
if (other.chunk_size_ != chunk_size_ || other.chunks_.size() != chunks_.size()) {
175+
other.chunk_mutex_.unlock();
176+
this->chunk_mutex_.unlock();
177+
return false;
178+
}
165179
chunks_vector::const_iterator chunk_iterator = chunks_.begin();
166180
chunks_vector::const_iterator other_iterator = other.chunks_.begin();
167181
for (; chunk_iterator != chunks_.begin() && other_iterator != other.chunks_.end();
168182
++chunk_iterator, ++other_iterator) {
169-
if (chunk_iterator->second != other_iterator->second) return false;
170-
if (strncmp(chunk_iterator->first, other_iterator->first, chunk_iterator->second)) return false;
183+
if (chunk_iterator->second != other_iterator->second ||
184+
strncmp(chunk_iterator->first, other_iterator->first, chunk_iterator->second)) {
185+
other.chunk_mutex_.unlock();
186+
this->chunk_mutex_.unlock();
187+
return false;
188+
}
171189
}
190+
other.chunk_mutex_.unlock();
191+
this->chunk_mutex_.unlock();
172192
return true;
173193
}
174194

195+
void request_storage_base_pimpl::swap(request_storage_base_pimpl &other) {
196+
lock(other.chunk_mutex_, this->chunk_mutex_);
197+
std::swap(chunk_size_, other.chunk_size_);
198+
std::swap(chunks_, other.chunks_);
199+
other.chunk_mutex_.unlock();
200+
this->chunk_mutex_.unlock();
201+
}
202+
175203
request_storage_base_pimpl::~request_storage_base_pimpl() {
176204
clear();
177205
}

libs/network/test/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ if (Boost_FOUND)
4545
set_source_files_properties(utils_thread_pool.cpp
4646
PROPERTIES COMPILE_FLAGS "-Wall")
4747
add_executable(cpp-netlib-utils_thread_pool utils_thread_pool.cpp)
48-
add_dependencies(cpp-netlib-utils_thread_pool
49-
cppnetlib-utils-thread_pool)
5048
target_link_libraries(cpp-netlib-utils_thread_pool
5149
cppnetlib-utils-thread_pool
5250
${Boost_LIBRARIES}

libs/network/test/http/request_test.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,16 @@ BOOST_AUTO_TEST_CASE(request_value_semantics) {
3131
// Next we modify the assigned object and make sure it's not the same as the
3232
// original.
3333
assigned.set_uri("http://www.google.com/");
34-
std::string original_uri, assigned_uri;
35-
original.get_uri(original_uri);
36-
assigned.get_uri(assigned_uri);
37-
BOOST_CHECK_NE(original_uri, assigned_uri);
34+
assigned.set_source("127.0.0.1");
35+
assigned.set_destination("http://www.google.com/");
36+
assigned.append_header("Connection", "close");
37+
assigned.set_body("Hello, world!");
3838
BOOST_CHECK(original != assigned);
3939
// Next we swap the assigned and copy.
4040
std::swap(assigned, copy);
4141
BOOST_CHECK(copy != assigned);
42-
BOOST_CHECK(assigned == original);
42+
BOOST_CHECK(copy != original);
43+
BOOST_CHECK(original == assigned);
4344
}
4445

4546
BOOST_AUTO_TEST_CASE(request_uri_test) {

0 commit comments

Comments
 (0)