$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r81088 - trunk/boost/thread
From: vicente.botet_at_[hidden]
Date: 2012-10-28 21:12:57
Author: viboes
Date: 2012-10-28 21:12:57 EDT (Sun, 28 Oct 2012)
New Revision: 81088
URL: http://svn.boost.org/trac/boost/changeset/81088
Log:
Thread: Added testable_mutex
Added:
   trunk/boost/thread/is_locked_by_this_thread.hpp   (contents, props changed)
   trunk/boost/thread/testable_mutex.hpp   (contents, props changed)
Added: trunk/boost/thread/is_locked_by_this_thread.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/is_locked_by_this_thread.hpp	2012-10-28 21:12:57 EDT (Sun, 28 Oct 2012)
@@ -0,0 +1,39 @@
+// (C) Copyright 2012 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_THREAD_IS_LOCKED_BY_THIS_THREAD_HPP
+#define BOOST_THREAD_IS_LOCKED_BY_THIS_THREAD_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+  template <typename Lockable>
+  class testable_mutex;
+
+  /**
+   * Overloaded function used to check if the mutex is locked when it is testable and do nothing otherwise.
+   *
+   * This function is used usually to assert the pre-condition when the function can only be called when the mutex
+   * must be locked by the current thread.
+   */
+  template <typename Lockable>
+  bool is_locked_by_this_thread(testable_mutex<Lockable> const& mtx)
+  {
+    return mtx.is_locked();
+  }
+  template <typename Lockable>
+  bool is_locked_by_this_thread(Lockable const&)
+  {
+    return true;
+  }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // header
Added: trunk/boost/thread/testable_mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/thread/testable_mutex.hpp	2012-10-28 21:12:57 EDT (Sun, 28 Oct 2012)
@@ -0,0 +1,142 @@
+// (C) Copyright 2012 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_THREAD_TESTABLE_LOCKABLE_HPP
+#define BOOST_THREAD_TESTABLE_LOCKABLE_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/detail/thread.hpp>
+
+#include <boost/atomic.hpp>
+#include <boost/assert.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+  /**
+   * Based on Associate Mutexes with Data to Prevent Races, By Herb Sutter, May 13, 2010
+   * http://www.drdobbs.com/windows/associate-mutexes-with-data-to-prevent-r/224701827?pgno=3
+   *
+   * Make our mutex testable if it isn't already.
+   *
+   * Many mutex services (including boost::mutex) don't provide a way to ask,
+   * "Do I already hold a lock on this mutex?"
+   * Sometimes it is needed to know if a method like is_held to be available.
+   * This wrapper associates an arbitrary lockable type with a thread id that stores the ID of the thread that
+   * currently holds the lockable. The thread id initially holds an invalid value that means no threads own the mutex.
+   * When we acquire a lock, we set the thread id; and when we release a lock, we reset it back to its default no id state.
+   *
+   */
+  template <typename Lockable>
+  class testable_mutex
+  {
+    Lockable mtx_;
+    atomic<thread::id> id_;
+  public:
+    /// the type of the wrapped lockable
+    typedef Lockable lockable_type;
+
+    /// Non copyable
+    BOOST_THREAD_NO_COPYABLE(testable_mutex)
+
+    void lock()
+    {
+      mtx_.lock();
+      id_ = this_thread::get_id();
+    }
+
+    void unlock()
+    {
+      BOOST_ASSERT(is_locked(mtx_));
+      id_ = thread::id();
+      mtx_.unlock();
+    }
+
+    bool try_lock()
+    {
+      if (mtx_.try_lock())
+      {
+        id_ = this_thread::get_id();
+        return true;
+      }
+      else
+      {
+        return false;
+      }
+    }
+#ifdef BOOST_THREAD_USES_CHRONO
+        template <class Rep, class Period>
+        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+        {
+          if (mtx_.try_lock_for(rel_time))
+          {
+            id_ = this_thread::get_id();
+            return true;
+          }
+          else
+          {
+            return false;
+          }
+        }
+        template <class Clock, class Duration>
+        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+        {
+          if (mtx_.try_lock_until(abs_time))
+          {
+            id_ = this_thread::get_id();
+            return true;
+          }
+          else
+          {
+            return false;
+          }
+        }
+#endif
+
+    bool is_locked_by_this_thread()
+    {
+      return this_thread::get_id() == id_;
+    }
+
+    bool get_id()
+    {
+      return id_;
+    }
+
+    // todo add the shared and upgrade mutex functions
+  };
+
+  template <typename Lockable>
+  struct is_testable_lockable : false_type
+  {};
+
+  template <typename Lockable>
+  struct is_testable_lockable<testable_mutex<Lockable> > : true_type
+  {};
+
+//  /**
+//   * Overloaded function used to check if the mutex is locked when it is testable and do nothing otherwise.
+//   *
+//   * This function is used usually to assert the pre-condition when the function can only be called when the mutex
+//   * must be locked by the current thread.
+//   */
+//  template <typename Lockable>
+//  bool is_locked_by_this_thread(testable_mutex<Lockable> const& mtx)
+//  {
+//    return mtx.is_locked();
+//  }
+//  template <typename Lockable>
+//  bool is_locked_by_this_thread(Lockable const&)
+//  {
+//    return true;
+//  }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // header