@@ -25,13 +25,14 @@ struct request_storage_base_pimpl {
2525void flatten (std::string &destination)const ;
2626void clear ();
2727bool equals (request_storage_base_pimplconst &other)const ;
28+ void swap (request_storage_base_pimpl &other);
2829~request_storage_base_pimpl ();
2930
3031private:
3132size_t chunk_size_;
3233typedef std::vector<std::pair<char *,size_t > > chunks_vector;
3334 chunks_vector chunks_;
34- mutexchunk_mutex ;
35+ mutable mutexchunk_mutex_ ;
3536
3637request_storage_base_pimpl (request_storage_base_pimplconst &other);
3738};
@@ -68,6 +69,10 @@ bool request_storage_base::equals(request_storage_base const &other) const {
6869return pimpl_->equals (*other.pimpl_ );
6970}
7071
72+ void request_storage_base::swap (request_storage_base &other) {
73+ return other.pimpl_ ->swap (*pimpl_);
74+ }
75+
7176request_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)
7883request_storage_base_pimpl::request_storage_base_pimpl (request_storage_base_pimplconst &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 ();
8389for (; it != other.chunks_ .end (); ++it) {
@@ -95,6 +101,7 @@ request_storage_base_pimpl * request_storage_base_pimpl::clone() const {
95101}
96102
97103void request_storage_base_pimpl::append (char const *data,size_t size) {
104+ lock_guard<mutex>scoped_lock (chunk_mutex_);
98105if (chunks_.empty ()) {
99106 chunks_.push_back (std::make_pair (
100107new (std::nothrow)char [chunk_size_],0 ));
@@ -121,6 +128,7 @@ void request_storage_base_pimpl::append(char const *data, size_t size) {
121128}
122129
123130size_t request_storage_base_pimpl::read (char *destination,size_t offset,size_t size)const {
131+ lock_guard<mutex>scoped_lock (chunk_mutex_);
124132if (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
147155void 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 ();
149158for (; chunk_iterator != chunks_.end (); ++chunk_iterator) {
150159 destination.append (chunk_iterator->first , chunk_iterator->second );
151160 }
152161}
153162
154163void request_storage_base_pimpl::clear () {
164+ lock_guard<mutex>scoped_lock (chunk_mutex_);
155165 chunks_vector::const_iterator chunk_iterator = chunks_.begin ();
156166for (; chunk_iterator != chunks_.end (); ++chunk_iterator) {
157167delete [] chunk_iterator->first ;
@@ -160,18 +170,36 @@ void request_storage_base_pimpl::clear() {
160170}
161171
162172bool request_storage_base_pimpl::equals (request_storage_base_pimplconst &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 ();
167181for (; 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 ();
172192return 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+
175203request_storage_base_pimpl::~request_storage_base_pimpl () {
176204clear ();
177205}