1 // Copyright (c) 2011-2016 Hartmut Kaiser 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #if !defined(HPX_IOSTREAMS_SERVER_BUFFER_JUL_18_2014_0715PM) 7 #define HPX_IOSTREAMS_SERVER_BUFFER_JUL_18_2014_0715PM 8 9 #include <hpx/config.hpp> 10 #include <hpx/lcos/local/recursive_mutex.hpp> 11 #include <hpx/runtime/serialization/serialization_fwd.hpp> 12 13 #include <hpx/components/iostreams/export_definitions.hpp> 14 #include <hpx/components/iostreams/write_functions.hpp> 15 16 #include <boost/swap.hpp> 17 18 #include <iosfwd> 19 #include <memory> 20 #include <mutex> 21 #include <utility> 22 #include <vector> 23 24 namespace hpx { namespace iostreams { namespace detail 25 { 26 struct buffer 27 { 28 protected: 29 typedef lcos::local::recursive_mutex mutex_type; 30 31 public: bufferhpx::iostreams::detail::buffer32 buffer() 33 : data_(new std::vector<char>), 34 mtx_(new mutex_type) 35 {} 36 bufferhpx::iostreams::detail::buffer37 buffer(buffer const& rhs) 38 : data_(rhs.data_) 39 , mtx_(rhs.mtx_) 40 {} 41 bufferhpx::iostreams::detail::buffer42 buffer(buffer && rhs) 43 : data_(std::move(rhs.data_)) 44 , mtx_(std::move(rhs.mtx_)) 45 {} 46 operator =hpx::iostreams::detail::buffer47 buffer& operator=(buffer const& rhs) 48 { 49 if (this != &rhs) 50 { 51 data_ = rhs.data_; 52 mtx_ = rhs.mtx_; 53 } 54 return *this; 55 } 56 operator =hpx::iostreams::detail::buffer57 buffer& operator=(buffer && rhs) 58 { 59 if (this != &rhs) 60 { 61 data_ = std::move(rhs.data_); 62 mtx_ = std::move(rhs.mtx_); 63 } 64 return *this; 65 } 66 emptyhpx::iostreams::detail::buffer67 bool empty() const 68 { 69 std::lock_guard<mutex_type> l(*mtx_); 70 return empty_locked(); 71 } 72 empty_lockedhpx::iostreams::detail::buffer73 bool empty_locked() const 74 { 75 return !data_.get() || data_->empty(); 76 } 77 inithpx::iostreams::detail::buffer78 buffer init() 79 { 80 std::lock_guard<mutex_type> l(*mtx_); 81 return init_locked(); 82 } 83 init_lockedhpx::iostreams::detail::buffer84 buffer init_locked() 85 { 86 buffer b; 87 boost::swap(b.data_, data_); 88 return b; 89 } 90 91 template <typename Char> writehpx::iostreams::detail::buffer92 std::streamsize write(Char const* s, std::streamsize n) 93 { 94 std::lock_guard<mutex_type> l(*mtx_); 95 std::copy(s, s + n, std::back_inserter(*data_)); 96 return n; 97 } 98 99 template <typename Mutex> writehpx::iostreams::detail::buffer100 void write(write_function_type const& f, Mutex& mtx) 101 { 102 std::unique_lock<mutex_type> l(*mtx_); 103 if (data_.get() && !data_->empty()) 104 { 105 std::shared_ptr<std::vector<char> > data(data_); 106 data_.reset(); 107 l.unlock(); 108 109 std::lock_guard<Mutex> ll(mtx); 110 f(*data); 111 } 112 } 113 114 private: 115 std::shared_ptr<std::vector<char> > data_; 116 117 protected: 118 std::shared_ptr<mutex_type> mtx_; 119 120 private: 121 friend class hpx::serialization::access; 122 123 HPX_IOSTREAMS_EXPORT void save( 124 serialization::output_archive& ar, unsigned) const; 125 HPX_IOSTREAMS_EXPORT void load( 126 serialization::input_archive& ar, unsigned); 127 128 HPX_SERIALIZATION_SPLIT_MEMBER(); 129 }; 130 }}} 131 132 #endif 133