@@ -25,13 +25,14 @@ struct request_storage_base_pimpl {
25
25
void flatten (std::string &destination) const ;
26
26
void clear ();
27
27
bool equals (request_storage_base_pimpl const &other) const ;
28
+ void swap (request_storage_base_pimpl &other);
28
29
~request_storage_base_pimpl ();
29
30
30
31
private:
31
32
size_t chunk_size_;
32
33
typedef std::vector<std::pair<char *, size_t > > chunks_vector;
33
34
chunks_vector chunks_;
34
- mutex chunk_mutex ;
35
+ mutable mutex chunk_mutex_ ;
35
36
36
37
request_storage_base_pimpl (request_storage_base_pimpl const &other);
37
38
};
@@ -68,6 +69,10 @@ bool request_storage_base::equals(request_storage_base const &other) const {
68
69
return pimpl_->equals (*other.pimpl_ );
69
70
}
70
71
72
+ void request_storage_base::swap (request_storage_base &other) {
73
+ return other.pimpl_ ->swap (*pimpl_);
74
+ }
75
+
71
76
request_storage_base_pimpl::request_storage_base_pimpl (size_t chunk_size)
72
77
: chunk_size_(chunk_size)
73
78
, chunks_()
@@ -78,6 +83,7 @@ request_storage_base_pimpl::request_storage_base_pimpl(size_t chunk_size)
78
83
request_storage_base_pimpl::request_storage_base_pimpl (request_storage_base_pimpl const &other)
79
84
: chunk_size_(other.chunk_size_)
80
85
, chunks_(0 ) {
86
+ lock_guard<mutex> scoped_lock (other.chunk_mutex_ );
81
87
chunks_.reserve (other.chunks_ .size ());
82
88
chunks_vector::const_iterator it = other.chunks_ .begin ();
83
89
for (; it != other.chunks_ .end (); ++it) {
@@ -95,6 +101,7 @@ request_storage_base_pimpl * request_storage_base_pimpl::clone() const {
95
101
}
96
102
97
103
void request_storage_base_pimpl::append (char const *data, size_t size) {
104
+ lock_guard<mutex> scoped_lock (chunk_mutex_);
98
105
if (chunks_.empty ()) {
99
106
chunks_.push_back (std::make_pair (
100
107
new (std::nothrow) char [chunk_size_], 0 ));
@@ -121,6 +128,7 @@ void request_storage_base_pimpl::append(char const *data, size_t size) {
121
128
}
122
129
123
130
size_t request_storage_base_pimpl::read (char *destination, size_t offset, size_t size) const {
131
+ lock_guard<mutex> scoped_lock (chunk_mutex_);
124
132
if (chunks_.empty ()) return 0 ;
125
133
// First we find which chunk we're going to read from using the provided
126
134
// 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
145
153
}
146
154
147
155
void request_storage_base_pimpl::flatten (std::string &destination) const {
156
+ lock_guard<mutex> scpoped_lock (chunk_mutex_);
148
157
chunks_vector::const_iterator chunk_iterator = chunks_.begin ();
149
158
for (; chunk_iterator != chunks_.end (); ++chunk_iterator) {
150
159
destination.append (chunk_iterator->first , chunk_iterator->second );
151
160
}
152
161
}
153
162
154
163
void request_storage_base_pimpl::clear () {
164
+ lock_guard<mutex> scoped_lock (chunk_mutex_);
155
165
chunks_vector::const_iterator chunk_iterator = chunks_.begin ();
156
166
for (; chunk_iterator != chunks_.end (); ++chunk_iterator) {
157
167
delete [] chunk_iterator->first ;
@@ -160,18 +170,36 @@ void request_storage_base_pimpl::clear() {
160
170
}
161
171
162
172
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
+ }
165
179
chunks_vector::const_iterator chunk_iterator = chunks_.begin ();
166
180
chunks_vector::const_iterator other_iterator = other.chunks_ .begin ();
167
181
for (; chunk_iterator != chunks_.begin () && other_iterator != other.chunks_ .end ();
168
182
++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
+ }
171
189
}
190
+ other.chunk_mutex_ .unlock ();
191
+ this ->chunk_mutex_ .unlock ();
172
192
return true ;
173
193
}
174
194
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
+
175
203
request_storage_base_pimpl::~request_storage_base_pimpl () {
176
204
clear ();
177
205
}
0 commit comments