$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r82318 - in trunk: boost/thread libs/thread/example
From: vicente.botet_at_[hidden]
Date: 2013-01-02 09:14:03
Author: viboes
Date: 2013-01-02 09:14:03 EST (Wed, 02 Jan 2013)
New Revision: 82318
URL: http://svn.boost.org/trac/boost/changeset/82318
Log:
Thread: complete externally_locked_stream.
Text files modified: 
   trunk/boost/thread/externally_locked_stream.hpp |   103 ++++++++++++++++++++++----------------- 
   trunk/libs/thread/example/not_interleaved.cpp   |    33 +++++++++---                            
   2 files changed, 82 insertions(+), 54 deletions(-)
Modified: trunk/boost/thread/externally_locked_stream.hpp
==============================================================================
--- trunk/boost/thread/externally_locked_stream.hpp	(original)
+++ trunk/boost/thread/externally_locked_stream.hpp	2013-01-02 09:14:03 EST (Wed, 02 Jan 2013)
@@ -4,12 +4,15 @@
 // http://www.boost.org/LICENSE_1_0.txt)
 
 
-#ifndef BOOST_THREAD_EXTERNALLY_LOCKED_HPP
-#define BOOST_THREAD_EXTERNALLY_LOCKED_HPP
+#ifndef BOOST_THREAD_EXTERNALLY_LOCKED_STREAM_HPP
+#define BOOST_THREAD_EXTERNALLY_LOCKED_STREAM_HPP
 
 #include <boost/thread/detail/config.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/detail/delete.hpp>
 
 #include <boost/thread/externally_locked.hpp>
+#include <boost/thread/lock_traits.hpp>
 #include <boost/thread/recursive_mutex.hpp>
 
 #include <boost/config/abi_prefix.hpp>
@@ -17,11 +20,11 @@
 namespace boost
 {
 
-  static recursive_mutex& terminal_mutex()
-  {
-    static recursive-mutex mtx;
-    return mtx;
-  }
+  //  inline static recursive_mutex& terminal_mutex()
+  //  {
+  //    static recursive_mutex mtx;
+  //    return mtx;
+  //  }
 
   template <typename Stream>
   class externally_locked_stream;
@@ -29,36 +32,47 @@
   template <class Stream>
   class stream_guard
   {
-    stream_guard(externally_locked_stream<Stream>& mtx, adopt_lock_t)
-    : mtx_(mtx)
+    stream_guard(externally_locked_stream<Stream>& mtx, adopt_lock_t) :
+      mtx_(mtx)
     {
     }
 
-    Stream& get() const
-    {
-      mtx_.get(*this);
-    }
 
-    friend class externally_locked_stream<Stream>;
+    friend class externally_locked_stream<Stream> ;
   public:
     typedef typename externally_locked_stream<Stream>::mutex_type mutex_type;
 
-    BOOST_THREAD_NO_COPYABLE( externally_locked_stream )
+    BOOST_THREAD_MOVABLE_ONLY( stream_guard)
 
-    stream_guard(externally_locked_stream<Stream>& mtx)
-    : mtx_(mtx)
+    stream_guard(externally_locked_stream<Stream>& mtx) :
+      mtx_(&mtx)
     {
       mtx.lock();
     }
 
+    stream_guard(BOOST_THREAD_RV_REF(stream_guard) rhs)
+    : mtx_(rhs.mtx_)
+    {
+      rhs.mtx_= 0;
+    }
+
     ~stream_guard()
     {
-      mtx_.unlock();
+      if (mtx_ != 0) mtx_->unlock();
     }
 
+    bool owns_lock(mutex_type const* l) const BOOST_NOEXCEPT
+    {
+      return l == mtx_->mutex();
+    }
+
+    Stream& get() const
+    {
+      return mtx_->get(*this);
+    }
 
   private:
-      externally_locked_stream<Stream>& mtx_;
+    externally_locked_stream<Stream>* mtx_;
   };
 
   template <typename Stream>
@@ -78,6 +92,8 @@
   {
     typedef externally_locked<Stream&, recursive_mutex> base_type;
   public:
+    BOOST_THREAD_NO_COPYABLE( externally_locked_stream)
+
     /**
      * Effects: Constructs an externally locked object storing the cloaked reference object.
      */
@@ -86,60 +102,57 @@
     {
     }
 
-
     stream_guard<Stream> hold()
     {
-      return stream_guard<Stream>(*this);
+      return stream_guard<Stream> (*this);
     }
 
   };
-//]
+  //]
 
   template <typename Stream, typename T>
-  const stream_guard<Stream>& operator<<(const stream_guard<Stream>& lck, T arg)
+  inline const stream_guard<Stream>& operator<<(const stream_guard<Stream>& lck, T arg)
   {
-      lck.get() << arg;
-      return lck;
+    lck.get() << arg;
+    return lck;
   }
 
   template <typename Stream>
-  const stream_guard<Stream>& operator<<(const stream_guard<Stream>& lck,
-                                        Stream& (*arg)(Stream&))
+  inline const stream_guard<Stream>& operator<<(const stream_guard<Stream>& lck, Stream& (*arg)(Stream&))
   {
-      lck.get() << arg;
-      return lck;
+    lck.get() << arg;
+    return lck;
   }
 
   template <typename Stream, typename T>
-  const stream_guard<Stream>& operator>>(const stream_guard<Stream>& lck, T& arg)
+  inline const stream_guard<Stream>& operator>>(const stream_guard<Stream>& lck, T& arg)
   {
-      lck.get() >> arg;
-      return lck;
+    lck.get() >> arg;
+    return lck;
   }
 
   template <typename Stream, typename T>
-  stream_guard<Stream> operator<<(externally_locked_stream<Stream>& mtx, T arg)
+  inline stream_guard<Stream> operator<<(externally_locked_stream<Stream>& mtx, T arg)
   {
-      mtx.lock();
-      mtx.get() << arg;
-      return stream_guard<Stream>(mtx, adopt_lock);
+    stream_guard<Stream> lk(mtx);
+    mtx.get(lk) << arg;
+    return boost::move(lk);
   }
 
   template <typename Stream>
-  stream_guard<Stream> operator<<(externally_locked_stream<Stream>& mtx,
-                                        Stream& (*arg)(Stream&))
+  inline stream_guard<Stream> operator<<(externally_locked_stream<Stream>& mtx, Stream& (*arg)(Stream&))
   {
-      mtx.lock();
-      mtx.get() << arg;
-      return stream_guard<Stream>(mtx, adopt_lock);
+    stream_guard<Stream> lk(mtx);
+    mtx.get(lk) << arg;
+    return boost::move(lk);
   }
 
   template <typename Stream, typename T>
-  stream_guard<Stream> operator>>(externally_locked_stream<Stream>& mtx, T& arg)
+  inline stream_guard<Stream> operator>>(externally_locked_stream<Stream>& mtx, T& arg)
   {
-      mtx.lock();
-      mtx.get() >> arg;
-      return stream_guard<Stream>(mtx, adopt_lock);
+    stream_guard<Stream> lk(mtx);
+    mtx.get(lk) >> arg;
+    return boost::move(lk);
   }
 
 }
Modified: trunk/libs/thread/example/not_interleaved.cpp
==============================================================================
--- trunk/libs/thread/example/not_interleaved.cpp	(original)
+++ trunk/libs/thread/example/not_interleaved.cpp	2013-01-02 09:14:03 EST (Wed, 02 Jan 2013)
@@ -6,9 +6,10 @@
 
 // adapted from the example given by Howard Hinnant in
 
+#define BOOST_THREAD_VERSION 4
 
 #include <iostream>
-#include <boost/thread/thread.hpp>
+#include <boost/thread/scoped_thread.hpp>
 #include <boost/thread/externally_locked_stream.hpp>
 
 void use_cerr(boost::externally_locked_stream<std::ostream> &mcerr)
@@ -18,7 +19,18 @@
   while (chrono::steady_clock::now() < tf)
   {
     mcerr << "logging data to cerr\n";
-    this_thread::sleep_for(milliseconds(500));
+    this_thread::sleep_for(chrono::milliseconds(500));
+  }
+}
+
+void use_cout(boost::externally_locked_stream<std::ostream> &mcout)
+{
+  using namespace boost;
+  auto tf = chrono::steady_clock::now() + chrono::seconds(5);
+  while (chrono::steady_clock::now() < tf)
+  {
+    mcout << "logging data to cout\n";
+    this_thread::sleep_for(chrono::milliseconds(250));
   }
 }
 
@@ -26,17 +38,20 @@
 {
   using namespace boost;
 
-  externally_locked_stream<std::ostream> mcerr(std::cerr, terminal_mutex());
-  externally_locked_stream<std::ostream> mcout(std::cerr, terminal_mutex());
-  externally_locked_stream<std::istream> mcin(std::cerr, terminal_mutex());
+  recursive_mutex terminal_mutex;
 
-  thread t1(use_cerr, mcerr);
-  this_thread::sleep_for(boost::chrono::seconds(2));
+  externally_locked_stream<std::ostream> mcerr(std::cerr, terminal_mutex);
+  externally_locked_stream<std::ostream> mcout(std::cout, terminal_mutex);
+  externally_locked_stream<std::istream> mcin(std::cin, terminal_mutex);
+
+  scoped_thread<> t1(thread(use_cerr, boost::ref(mcerr)));
+  scoped_thread<> t2(thread(use_cout, boost::ref(mcout)));
+  this_thread::sleep_for(chrono::seconds(2));
   std::string nm;
   mcout << "Enter name: ";
-  mcin >> nm;
+  //mcin >> nm;
   t1.join();
   mcout << nm << '\n';
-  return 0;
+  return 1;
 }