Chris@16: // (C) Copyright 2012 Vicente J. Botet Escriba Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: Chris@16: #ifndef BOOST_THREAD_EXTERNALLY_LOCKED_STREAM_HPP Chris@16: #define BOOST_THREAD_EXTERNALLY_LOCKED_STREAM_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: Chris@16: template Chris@16: class externally_locked_stream; Chris@16: Chris@16: template Chris@16: class stream_guard Chris@16: { Chris@16: Chris@16: friend class externally_locked_stream ; Chris@16: public: Chris@16: typedef typename externally_locked_stream::mutex_type mutex_type; Chris@16: Chris@16: BOOST_THREAD_MOVABLE_ONLY( stream_guard) Chris@16: Chris@16: stream_guard(externally_locked_stream& mtx) : Chris@16: mtx_(&mtx) Chris@16: { Chris@16: mtx.lock(); Chris@16: } Chris@16: Chris@16: stream_guard(externally_locked_stream& mtx, adopt_lock_t) : Chris@16: mtx_(&mtx) Chris@16: { Chris@16: } Chris@16: Chris@16: stream_guard(BOOST_THREAD_RV_REF(stream_guard) rhs) BOOST_NOEXCEPT Chris@16: : mtx_(rhs.mtx_) Chris@16: { Chris@16: rhs.mtx_= 0; Chris@16: } Chris@16: Chris@16: ~stream_guard() Chris@16: { Chris@16: if (mtx_ != 0) mtx_->unlock(); Chris@16: } Chris@16: Chris@16: bool owns_lock(const mutex_type * l) const BOOST_NOEXCEPT Chris@16: { Chris@16: return l == mtx_->mutex(); Chris@16: } Chris@16: Chris@16: /** Chris@16: * @Requires mtx_ Chris@16: */ Chris@16: Stream& get() const Chris@16: { Chris@16: BOOST_THREAD_ASSERT_PRECONDITION( mtx_, lock_error() ); Chris@16: return mtx_->get(*this); Chris@16: } Chris@16: Stream& bypass() const Chris@16: { Chris@16: return get(); Chris@16: } Chris@16: Chris@16: Chris@16: private: Chris@16: externally_locked_stream* mtx_; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_strict_lock_sur_parole > : true_type Chris@16: { Chris@16: }; Chris@16: Chris@16: /** Chris@16: * externally_locked_stream cloaks a reference to an stream of type Stream, and actually Chris@16: * provides full access to that object through the get and set member functions, provided you Chris@16: * pass a reference to a strict lock object. Chris@16: */ Chris@16: Chris@16: //[externally_locked_stream Chris@16: template Chris@16: class externally_locked_stream: public externally_locked Chris@16: { Chris@16: typedef externally_locked base_type; Chris@16: public: Chris@16: BOOST_THREAD_NO_COPYABLE( externally_locked_stream) Chris@16: Chris@16: /** Chris@16: * Effects: Constructs an externally locked object storing the cloaked reference object. Chris@16: */ Chris@16: externally_locked_stream(Stream& stream, RecursiveMutex& mtx) BOOST_NOEXCEPT : Chris@16: base_type(stream, mtx) Chris@16: { Chris@16: } Chris@16: Chris@16: stream_guard hold() BOOST_NOEXCEPT Chris@16: { Chris@16: return stream_guard (*this); Chris@16: } Chris@16: Stream& bypass() const Chris@16: { Chris@16: stream_guard lk(*this); Chris@16: return get(lk); Chris@16: } Chris@16: }; Chris@16: //] Chris@16: Chris@16: template Chris@16: inline const stream_guard& operator<<(const stream_guard& lck, T arg) Chris@16: { Chris@16: lck.get() << arg; Chris@16: return lck; Chris@16: } Chris@16: Chris@16: template Chris@16: inline const stream_guard& operator<<(const stream_guard& lck, Stream& (*arg)(Stream&)) Chris@16: { Chris@16: lck.get() << arg; Chris@16: return lck; Chris@16: } Chris@16: Chris@16: template Chris@16: inline const stream_guard& operator>>(const stream_guard& lck, T& arg) Chris@16: { Chris@16: lck.get() >> arg; Chris@16: return lck; Chris@16: } Chris@16: Chris@16: template Chris@16: inline stream_guard operator<<(externally_locked_stream& mtx, T arg) Chris@16: { Chris@16: stream_guard lk(mtx); Chris@16: mtx.get(lk) << arg; Chris@16: return boost::move(lk); Chris@16: } Chris@16: Chris@16: template Chris@16: inline stream_guard operator<<(externally_locked_stream& mtx, Stream& (*arg)(Stream&)) Chris@16: { Chris@16: stream_guard lk(mtx); Chris@16: mtx.get(lk) << arg; Chris@16: return boost::move(lk); Chris@16: } Chris@16: Chris@16: template Chris@16: inline stream_guard operator>>(externally_locked_stream& mtx, T& arg) Chris@16: { Chris@16: stream_guard lk(mtx); Chris@16: mtx.get(lk) >> arg; Chris@16: return boost::move(lk); Chris@16: } Chris@16: Chris@16: } Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // header