Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r51156 - sandbox/synchro/boost/synchro/lockers
From: vicente.botet_at_[hidden]
Date: 2009-02-09 17:34:45


Author: viboes
Date: 2009-02-09 17:34:44 EST (Mon, 09 Feb 2009)
New Revision: 51156
URL: http://svn.boost.org/trac/boost/changeset/51156

Log:
Boost.Synchro V0.0.0
Added:
   sandbox/synchro/boost/synchro/lockers/condition_locker.hpp (contents, props changed)
   sandbox/synchro/boost/synchro/lockers/externally_locked.hpp (contents, props changed)
   sandbox/synchro/boost/synchro/lockers/is_strict_locker.hpp (contents, props changed)
   sandbox/synchro/boost/synchro/lockers/locking_ptr.hpp (contents, props changed)
   sandbox/synchro/boost/synchro/lockers/on_dereference_locking_ptr.hpp (contents, props changed)
   sandbox/synchro/boost/synchro/lockers/priority_write.hpp (contents, props changed)
   sandbox/synchro/boost/synchro/lockers/reverse_lock.hpp (contents, props changed)
   sandbox/synchro/boost/synchro/lockers/strict_locker.hpp (contents, props changed)

Added: sandbox/synchro/boost/synchro/lockers/condition_locker.hpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/boost/synchro/lockers/condition_locker.hpp 2009-02-09 17:34:44 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,537 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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)
+//
+// See http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_SYNCHRO_CONDITION_LOCKER__HPP
+#define BOOST_SYNCHRO_CONDITION_LOCKER__HPP
+
+#include <boost/synchro/lockable_concepts.hpp>
+#include <boost/thread/condition.hpp>
+#include "boost/synchro/thread/mutex.hpp"
+
+namespace boost { namespace synchro {
+
+
+
+template <
+ class Condition
+>
+class condition_backdoor;
+
+template <
+ class Condition
+>
+class condition_safe_boosted {
+public:
+ typedef Condition condition;
+ typedef condition_backdoor<Condition> backdoor;
+ friend class condition_backdoor<Condition>;
+private:
+ template <typename Locker>
+ void notify_one(Locker& lock) {
+ ++num_notifies_requested;
+ if (num_blocked > 0) {
+ cond_.notify_one();
+ ++num_notifies_done;
+ }
+ }
+ template <typename Locker>
+ void notify_all(Locker& lock) {
+ ++num_notifies_requested;
+ if (num_blocked > 0) {
+ cond_.notify_all();
+ ++num_notifies_done;
+ }
+ }
+ template <typename Locker, typename Predicate>
+ void wait_when(Locker& lock, Predicate pred) {
+ while(!pred()) wait(lock);
+ }
+ template <typename Locker>
+ void wait(Locker& lock) {
+ ++num_waits;
+ ++num_blocked;
+ cond_.wait(lock);
+ --num_blocked;
+ }
+
+ template <typename Locker>
+ bool wait_until(Locker& lock, boost::system_time const& abs_time) {
+ ++num_waits;
+ ++num_blocked;
+ bool b = cond_.timed_wait(lock);
+ --num_blocked;
+ return b;
+ }
+
+ template<typename Locker, typename duration_type>
+ bool wait_for(Locker& lock,duration_type const& rel_time) {
+ ++num_waits;
+ ++num_blocked;
+ bool b =cond_.timed_wait(lock);
+ --num_blocked;
+ return b;
+ }
+
+ template<typename Locker, typename predicate_type>
+ bool wait_when_until(Locker& lock, predicate_type pred, boost::system_time const& abs_time) {
+ while (!pred())
+ {
+ if(!wait_until(lock, abs_time))
+ return pred();
+ }
+ return true;
+ }
+ template<typename Locker, typename duration_type, typename predicate_type>
+ bool wait_when_for(Locker& lock, predicate_type pred, duration_type const& rel_time) {
+ while (!pred())
+ {
+ if(!wait_for(lock, rel_time))
+ return pred();
+ }
+ return true;
+ }
+private:
+ Condition cond_;
+ unsigned num_blocked;
+ unsigned num_waits;
+ unsigned num_notifies_requested;
+ unsigned num_notifies_done;
+};
+
+template <
+ class Condition
+>
+class condition_safe {
+public:
+ typedef Condition condition;
+ typedef condition_backdoor<Condition> backdoor;
+ void notify_one() { cond_.notify_one(); }
+ void notify_all() { cond_.notify_all(); }
+private:
+ friend class condition_backdoor<Condition>;
+ template <typename Locker, typename Predicate>
+ void wait_when(Locker& lock, Predicate pred) {
+ cond_.wait(lock, pred);
+ }
+ template <typename Locker>
+ void wait(Locker& lock) {
+ cond_.wait(lock);
+ }
+
+ template <typename Locker>
+ bool wait_until(Locker& lock, boost::system_time const& abs_time) {
+ return cond_.timed_wait(lock);;
+ }
+
+ template<typename Locker, typename duration_type>
+ bool wait_for(Locker& lock,duration_type const& rel_time) {
+ return cond_.timed_wait(lock);
+ }
+
+// template<typename Locker, typename predicate_type>
+// bool wait_when(Locker& lock, predicate_type pred) {
+// return cond_.wait(lock, pred);
+// }
+ template<typename Locker, typename predicate_type>
+ bool wait_when_until(Locker& lock, predicate_type pred, boost::system_time const& abs_time) {
+ return cond_.timed_wait(lock, pred, abs_time);
+ }
+ template<typename Locker, typename duration_type, typename predicate_type>
+ bool wait_when_for(Locker& lock, predicate_type pred, duration_type const& rel_time) {
+ return cond_.timed_wait(lock, pred, rel_time);
+ }
+private:
+ Condition cond_;
+};
+
+template <
+ class Condition
+>
+struct condition_backdoor {
+ condition_backdoor(condition_safe<Condition>&cnd): that_(cnd) {}
+ template <typename Locker, typename Predicate>
+ void wait_when(Locker& lock, Predicate pred){
+ that_.wait_when(lock, pred);
+ }
+ template <typename Locker>
+ void wait(Locker& lock) {
+ that_.wait(lock);
+ }
+ template <typename Locker>
+ bool wait_until(Locker& lock, boost::system_time const& abs_time) {
+ return that_.wait_until(lock, abs_time);
+ }
+
+ template<typename Locker, typename duration_type>
+ bool wait_for(Locker& lock, duration_type const& rel_time) {
+ return that_.wait_for(lock, rel_time);
+ }
+
+ template<typename Locker, typename predicate_type>
+ bool wait_when_until(Locker& lock, predicate_type pred, boost::system_time const& abs_time) {
+ return that_.timed_wait(lock, pred, abs_time);
+ }
+ template <typename Locker>
+ void notify_one(Locker& lock) {
+ that_.notify_one(lock);
+ }
+ template <typename Locker>
+ void notify_all(Locker& lock) {
+ that_.notify_all(lock);
+ }
+private:
+ condition_safe<Condition>& that_;
+};
+
+#if 0
+//[condition_unique_locker
+template <
+ typename Lockable,
+ class Condition=condition_safe<typename best_condition<Lockable>::type >
+>
+class condition_unique_locker
+ : protected unique_lock<Lockable>
+{
+ BOOST_CONCEPT_ASSERT((LockableConcept<Lockable>));
+ typedef unique_lock<Lockable> super_type;
+public:
+ typedef Lockable lockable_type;
+ typedef Condition condition;
+
+ explicit condition_unique_locker(lockable_type& obj); /*< locks on construction >*/
+ condition_unique_locker(lockable_type& obj, condition &cond); /*< relock on condition >*/
+ template <typename Predicate>
+ condition_unique_locker(lockable_type& obj, condition &cond, Predicate pred); /*< relock condition when predicate satisfaied>*/
+ ~condition_unique_locker() /*< unlocks on destruction >*/
+
+ typedef bool (condition_unique_locker::*bool_type)() const; /*< safe bool idiom >*/
+ operator bool_type() const; /*< always owned >*/
+ bool operator!() const { return false; } /*< always owned >*/
+ bool owns_lock() const { return true; } /*< always owned >*/
+ bool is_locking(lockable_type* l) const /*< strict lockers specific function >*/
+
+ void relock_on(condition & cond);
+ void relock_until(condition & cond, boost::system_time const& abs_time);
+ template<typename duration_type>
+ void relock_on_for(condition & cond, duration_type const& rel_time);
+
+ template<typename Predicate>
+ void relock_when(condition &cond, Predicate pred);
+ template<typename Predicate>
+ void relock_when_until(condition &cond, Predicate pred,
+ boost::system_time const& abs_time);
+ template<typename Predicate, typename duration_type>
+ void relock_when_for(condition &cond, Predicate pred,
+ duration_type const& rel_time);
+
+ void notify_one(condition_boosted &cond);
+ void notify_all(condition_boosted &cond);
+
+ /*< no possibility to unlock without blocking on wait... >*/
+
+};
+//]
+#endif
+
+template <
+ typename Lockable,
+ class Condition=condition_safe<typename best_condition<Lockable>::type >,
+ class ConditionBoosted=condition_safe_boosted<typename best_condition<Lockable>::type >
+>
+class condition_unique_locker
+ : protected unique_lock<Lockable>
+{
+ BOOST_CONCEPT_ASSERT((LockableConcept<Lockable>));
+ typedef unique_lock<Lockable> super_type;
+public:
+ typedef Lockable lockable_type;
+ typedef Condition condition;
+ typedef ConditionBoosted condition_boosted;
+
+ explicit condition_unique_locker(lockable_type& obj)
+ : super_type(obj) { } /*< locks on construction >*/
+
+ condition_unique_locker(lockable_type& obj, condition &cond)
+ : super_type(obj) {
+ typename condition::backdoor(cond).wait(*static_cast<unique_lock<Lockable>*>(this)); /*< relock on condition >*/
+ }
+ condition_unique_locker(lockable_type& obj, condition_boosted &cond)
+ : super_type(obj) {
+ typename condition::backdoor(cond).wait(*static_cast<unique_lock<Lockable>*>(this)); /*< relock on condition >*/
+ }
+
+ template <typename Predicate>
+ condition_unique_locker(lockable_type& obj, condition &cond, Predicate pred)
+ : super_type(obj) {
+ typename condition::backdoor(cond).wait_when(*static_cast<unique_lock<Lockable>*>(this), pred); /*< relock condition when predicate satisfaied>*/
+ }
+ template <typename Predicate>
+ condition_unique_locker(lockable_type& obj, condition_boosted &cond, Predicate pred)
+ : super_type(obj) {
+ typename condition::backdoor(cond).wait_when(*static_cast<unique_lock<Lockable>*>(this), pred); /*< relock condition when predicate satisfaied>*/
+ }
+
+ ~condition_unique_locker() { } /*< unlocks on destruction >*/
+
+ typedef bool (condition_unique_locker::*bool_type)() const; /*< safe bool idiom >*/
+ operator bool_type() const { return &condition_unique_locker::owns_lock; }
+ bool operator!() const { return false; } /*< always owned >*/
+ bool owns_lock() const { return true; }
+ bool is_locking(lockable_type* l) const { return l==mutex(); } /*< strict lockers specific function >*/
+
+ void relock_on(condition & cond) {
+ typename condition::backdoor(cond).wait(*this);
+ }
+ void relock_on(condition_boosted & cond) {
+ typename condition::backdoor(cond).wait(*this);
+ }
+
+ void relock_until(condition & cond, boost::system_time const& abs_time) {
+ typename condition::backdoor(cond).wait_until(*this, abs_time);
+ }
+ void relock_until(condition_boosted & cond, boost::system_time const& abs_time) {
+ typename condition::backdoor(cond).wait_until(*this, abs_time);
+ }
+
+ template<typename duration_type>
+ void relock_on_for(condition & cond, duration_type const& rel_time) {
+ typename condition::backdoor(cond).wait_for(*this, rel_time);
+ }
+ template<typename duration_type>
+ void relock_on_for(condition_boosted & cond, duration_type const& rel_time) {
+ typename condition::backdoor(cond).wait_for(*this, rel_time);
+ }
+
+ template<typename Predicate>
+ void relock_when(condition &cond, Predicate pred){
+ typename condition::backdoor(cond).wait_when(*this, pred);
+ }
+ template<typename Predicate>
+ void relock_when(condition_boosted &cond, Predicate pred){
+ typename condition::backdoor(cond).wait_when(*this, pred);
+ }
+
+ template<typename Predicate>
+ void relock_when_until(condition &cond, Predicate pred,
+ boost::system_time const& abs_time){
+ typename condition::backdoor(cond).wait_when_until(*this, pred, abs_time);
+ }
+ template<typename Predicate>
+ void relock_when_until(condition_boosted &cond, Predicate pred,
+ boost::system_time const& abs_time){
+ typename condition::backdoor(cond).wait_when_until(*this, pred, abs_time);
+ }
+
+ template<typename Predicate, typename duration_type>
+ void relock_when_for(condition &cond, Predicate pred,
+ duration_type const& rel_time){
+ typename condition::backdoor(cond).wait_when_for(*this, pred, rel_time);
+ }
+ template<typename Predicate, typename duration_type>
+ void relock_when_for(condition_boosted &cond, Predicate pred,
+ duration_type const& rel_time){
+ typename condition::backdoor(cond).wait_when_for(*this, pred, rel_time);
+ }
+
+ void notify_one(condition_boosted &cond){
+ typename condition::backdoor(cond).notify_one(*this);
+ }
+ void notify_all(condition_boosted &cond){
+ typename condition::backdoor(cond).notify_all(*this);
+ }
+
+ /*< no possibility to unlock without blocking on wait... >*/
+
+private:
+ friend class boost::condition_variable;
+ Lockable* mutex() { return this->super_type::mutex(); }
+ friend class boost::condition_variable_any;
+ void lock() {this->super_type::lock();}
+ void unlock() {this->super_type::unlock();}
+ bool try_lock() { return this->super_type::try_lock();}
+
+};
+
+//[condition_shared_locker
+template <
+ typename Lockable,
+ class Condition=condition_safe<typename best_condition_any<Lockable>::type >,
+ class ConditionBoosted=condition_safe_boosted<typename best_condition_any<Lockable>::type >
+>
+class condition_shared_locker
+ : protected shared_lock<Lockable> {
+ BOOST_CONCEPT_ASSERT((LockableConcept<Lockable>));
+ typedef shared_lock<Lockable> super_type;
+public:
+ typedef Lockable lockable_type;
+ typedef Condition condition;
+ typedef ConditionBoosted condition_boosted;
+
+ explicit condition_shared_locker(lockable_type& obj)
+ : super_type(obj) { } /*< locks on construction >*/
+ condition_shared_locker(lockable_type& obj, condition &cond)
+ : super_type(obj) {
+ typename condition::backdoor(cond).wait(*this); /*< relock on condition >*/
+ }
+ condition_shared_locker(lockable_type& obj, condition_boosted &cond)
+ : super_type(obj) {
+ typename condition::backdoor(cond).wait(*this); /*< relock on condition >*/
+ }
+ template <typename Predicate>
+ condition_shared_locker(lockable_type& obj, condition &cond, Predicate pred)
+ : super_type(obj) {
+ typename condition::backdoor(cond).wait(*this, pred); /*< relock condition when predicate satisfaied>*/
+ }
+ template <typename Predicate>
+ condition_shared_locker(lockable_type& obj, condition_boosted &cond, Predicate pred)
+ : super_type(obj) {
+ typename condition::backdoor(cond).wait(*this, pred); /*< relock condition when predicate satisfaied>*/
+ }
+ ~condition_shared_locker() { } /*< unlocks on destruction >*/
+
+ typedef bool (condition_shared_locker::*bool_type)() const; /*< safe bool idiom >*/
+ operator bool_type() const { return &condition_shared_locker::owns_lock; }
+ bool operator!() const { return false; } /*< always owned >*/
+ bool owns_lock() const { return true; }
+ bool is_locking(lockable_type* l) const { return l==mutex(); } /*< strict lockers specific function >*/
+
+ void relock_on(condition & cond) {
+ typename condition::backdoor(cond).wait(*this);
+ }
+ void relock_on(condition_boosted & cond) {
+ typename condition::backdoor(cond).wait(*this);
+ }
+
+ void relock_until(condition & cond, boost::system_time const& abs_time) {
+ typename condition::backdoor(cond).wait_until(*this, abs_time);
+ }
+ void relock_until(condition_boosted & cond, boost::system_time const& abs_time) {
+ typename condition::backdoor(cond).wait_until(*this, abs_time);
+ }
+
+ template<typename duration_type>
+ void relock_on_for(condition & cond, duration_type const& rel_time) {
+ typename condition::backdoor(cond).wait_for(*this, rel_time);
+ }
+ template<typename duration_type>
+ void relock_on_for(condition_boosted & cond, duration_type const& rel_time) {
+ typename condition::backdoor(cond).wait_for(*this, rel_time);
+ }
+
+ template<typename Predicate>
+ void relock_when(condition &cond, Predicate pred){
+ typename condition::backdoor(cond).wait_when(*this, pred);
+ }
+ template<typename Predicate>
+ void relock_when(condition_boosted &cond, Predicate pred){
+ typename condition::backdoor(cond).wait_when(*this, pred);
+ }
+
+ template<typename Predicate>
+ void relock_when_until(condition &cond, Predicate pred,
+ boost::system_time const& abs_time){
+ typename condition::backdoor(cond).wait_when_until(*this, pred, abs_time);
+ }
+ template<typename Predicate>
+ void relock_when_until(condition_boosted &cond, Predicate pred,
+ boost::system_time const& abs_time){
+ typename condition::backdoor(cond).wait_when_until(*this, pred, abs_time);
+ }
+
+ template<typename Predicate, typename duration_type>
+ void relock_when_for(condition &cond, Predicate pred,
+ duration_type const& rel_time){
+ typename condition::backdoor(cond).wait_when_for(*this, pred, rel_time);
+ }
+ template<typename Predicate, typename duration_type>
+ void relock_when_for(condition_boosted &cond, Predicate pred,
+ duration_type const& rel_time){
+ typename condition::backdoor(cond).wait_when_for(*this, pred, rel_time);
+ }
+
+ /*< no possibility to unlock without blocking on wait>*/
+
+private:
+ friend class boost::condition_variable;
+ Lockable* mutex() { return this->super_type::mutex(); }
+ friend class boost::condition_variable_any;
+ void lock() {this->super_type::lock();}
+ void unlock() {this->super_type::unlock();}
+ bool try_lock() { return this->super_type::try_lock();}
+};
+//]
+
+
+
+//[condition_lockable
+template <
+ typename Lockable,
+ class Condition=condition_safe<typename best_condition<Lockable>::type >
+>
+class condition_lockable
+ : protected Lockable
+{
+ BOOST_CONCEPT_ASSERT((LockableConcept<Lockable>));
+ typedef Lockable super_type;
+public:
+ typedef Lockable lockable_type;
+ typedef Condition condition;
+
+ condition_lockable()
+ : super_type() { }
+
+ ~condition_lockable() { }
+
+ void relock_on(condition & cond) {
+ typename condition::backdoor(cond).wait(*this);
+ }
+
+ void relock_until(condition & cond, boost::system_time const& abs_time) {
+ typename condition::backdoor(cond).wait_until(*this, abs_time);
+ }
+
+ template<typename duration_type>
+ void relock_on_for(condition & cond, duration_type const& rel_time) {
+ typename condition::backdoor(cond).wait_for(*this, rel_time);
+ }
+
+ template<typename Predicate>
+ void relock_when(condition &cond, Predicate pred){
+ typename condition::backdoor(cond).wait_when(*this, pred);
+ }
+
+ template<typename Predicate>
+ void relock_when_until(condition &cond, Predicate pred,
+ boost::system_time const& abs_time){
+ typename condition::backdoor(cond).wait_when_until(*this, pred, abs_time);
+ }
+
+ template<typename Predicate, typename duration_type>
+ void relock_when_for(condition &cond, Predicate pred,
+ duration_type const& rel_time){
+ typename condition::backdoor(cond).wait_when_for(*this, pred, rel_time);
+ }
+
+ void notify_one(condition &cond){
+ typename condition::backdoor(cond).notify_one(*this);
+ }
+ void notify_all(condition &cond){
+ typename condition::backdoor(cond).notify_all(*this);
+ }
+
+private:
+ friend class boost::condition_variable;
+ friend class boost::condition_variable_any;
+};
+//]
+
+}
+}
+#endif

Added: sandbox/synchro/boost/synchro/lockers/externally_locked.hpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/boost/synchro/lockers/externally_locked.hpp 2009-02-09 17:34:44 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,110 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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)
+//
+// See http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_SYNCHRO_EXTERNALLY_LOCKED__HPP
+#define BOOST_SYNCHRO_EXTERNALLY_LOCKED__HPP
+
+#include "boost/synchro/lockers/is_strict_locker.hpp"
+#include "boost/synchro/lockers/strict_locker.hpp"
+#include "boost/synchro/syntactic_lock_traits.hpp"
+#include "boost/synchro/lockable_traits.hpp"
+#include "boost/static_assert.hpp"
+#include "boost/type_traits/is_same.hpp"
+#include "boost/synchro/lockable_concepts.hpp"
+#include "boost/thread/exceptions.hpp"
+
+namespace boost { namespace synchro {
+
+/**
+ * externally_locked cloaks an object of type T, and actually provides full
+ * access to that object through the get and set member functions, provided you
+ * pass a reference to a strict_locker<Owner> object
+ */
+
+//[externally_locked
+template <typename T, typename Lockable>
+class externally_locked {
+ BOOST_CONCEPT_ASSERT((LockableConcept<Lockable>));
+
+// /*<-*/ typedef boost::lock_error lock_error; /*->*/
+ typedef typename syntactic_lock_traits<Lockable>::lock_error lock_error; /*< needed until Boost Thread and Interprocess unify the exceptions >*/
+public:
+ externally_locked(T& obj, Lockable& lockable)
+ : obj_(obj)
+ , lockable_(lockable)
+ {}
+
+ externally_locked(Lockable& lockable)
+ : obj_()
+ , lockable_(lockable)
+ {}
+
+ T& get(strict_locker<Lockable>& locker) {
+
+#ifndef BOOST_SYNCHRO_EXTERNALLY_LOCKED_DONT_CHECK_SAME /*< define BOOST_SYNCHRO_EXTERNALLY_LOCKED_DONT_CHECK_SAME if you don't want to check locker check the same lockable >*/
+ if (!locker.is_locking(&lockable_)) throw lock_error(); /*< run time check throw if not locks the same >*/
+#endif
+ return obj_;
+ }
+ void set(const T& obj, Lockable& lockable) {
+ obj_ = obj;
+ lockable_=lockable;
+ }
+private:
+ T obj_;
+ Lockable& lockable_;
+};
+//]
+
+//[externally_locked_any
+template <typename T, typename Lockable>
+class externally_locked_any {
+ /*<-*/ typedef typename syntactic_lock_traits<Lockable>::lock_error lock_error; /*->*/
+// /*<-*/ typedef boost::lock_error lock_error; /*->*/
+public:
+/*<-*/ externally_locked_any(T& obj, Lockable& lockable)
+ : obj_(obj)
+ , lockable_(lockable)
+ {}
+
+ externally_locked_any(Lockable& lockable)
+ : obj_()
+ , lockable_(lockable)
+ {}/*->*/
+ // ... as before
+ template <class Locker>
+ T& get(Locker& locker) {
+ BOOST_CONCEPT_ASSERT((StrictLockerConcept<Locker>));
+
+ BOOST_STATIC_ASSERT((is_strict_locker<Locker>::value)); /*< locker is a strict locker "sur parolle" >*/
+ BOOST_STATIC_ASSERT((is_same<Lockable,
+ typename lockable_type<Locker>::type>::value)); /*< that locks the same type >*/
+#ifndef BOOST_SYNCHRO_EXTERNALLY_LOCKED_DONT_CHECK_OWNERSHIP /*< define BOOST_SYNCHRO_EXTERNALLY_LOCKED_NO_CHECK_OWNERSHIP if you don't want to check locker ownership >*/
+ if (! locker ) throw lock_error(); /*< run time check throw if no locked >*/
+#endif
+#ifndef BOOST_SYNCHRO_EXTERNALLY_LOCKED_DONT_CHECK_SAME
+ if (!locker.is_locking(&lockable_)) throw lock_error();
+#endif
+ return obj_;
+ }
+/*<-*/
+ void set(const T& obj, Lockable& lockable) {
+ obj_ = obj;
+ lockable_=lockable;
+ }
+private:
+ T obj_;
+ Lockable& lockable_;
+/*->*/
+};
+//]
+}
+}
+#endif

Added: sandbox/synchro/boost/synchro/lockers/is_strict_locker.hpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/boost/synchro/lockers/is_strict_locker.hpp 2009-02-09 17:34:44 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,31 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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)
+//
+// See http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_SYNCHRO_IS_STRICT_LOCKER__HPP
+#define BOOST_SYNCHRO_IS_STRICT_LOCKER__HPP
+
+#include "boost/mpl/bool.hpp"
+
+namespace boost { namespace synchro {
+
+/**
+ * An strict locker is a locker ensuring the mutex is locked on the scope of the lock
+ * There is no only one way to define a strict lock as the strict_locker and
+ * nesteed_strict_locker shows. So we need a metafunction that states if a
+ * locker is a strict locker
+ */
+
+template <typename Locker>
+struct is_strict_locker : mpl::false_ {};
+
+}
+}
+
+#endif

Added: sandbox/synchro/boost/synchro/lockers/locking_ptr.hpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/boost/synchro/lockers/locking_ptr.hpp 2009-02-09 17:34:44 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,265 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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)
+//
+// See http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_SYNCHRO_LOCKING_PTR__HPP
+#define BOOST_SYNCHRO_LOCKING_PTR__HPP
+
+#include "boost/noncopyable.hpp"
+#include "boost/thread/mutex.hpp"
+
+namespace boost { namespace synchro {
+/**
+* templated with the type of the controlled variable, and the mutex type.
+* @use For example, if you want to control a Product_Queue, you use a
+* locking_ptr <Product_Queue> that you initialize with a variable of type volatile Product_Queue.
+* <code>
+* volatile Product_Queue& q;
+* boost::mutex m;
+* locking_ptr <const Product_Queue> q_lptr(q, m);
+* // q_lptr allows to access all the Product_Queue function
+* <code>
+
+* <code>
+* volatile const Product_Queue& q;
+* rw_mutex m;
+* rw_locking_ptr <const Product_Queue, mutex> q_rlptr(q, m);
+* // q_rlptr allows to access all the const Product_Queue function by read locking the mutex
+* <code>
+
+* <code>
+* volatile Product_Queue& wq;
+* rw_mutex m;
+* rw_locking_ptr <Product_Queue, mutex> q_wlptr(wq, m);
+* // q_wlptr allows to access all the wq Product_Queue function by write locking the mutex
+* <code>
+
+* <code>
+* volatile Product_Queue& wq;
+* rw_mutex m;
+* {
+* rw_locking_ptr <const Product_Queue, mutex> q_rlptr(wq, m);
+* // q_rlptr allows to access all the const Product_Queue function by read locking the mutex
+* {
+* rw_promoting_ptr <Product_Queue, mutex> q_wlptr(q_rlptr);
+* // q_wlptr allows to access all the wq Product_Queue function by write locking the mutex
+* }
+* }
+* <code>
+
+* <code>
+* volatile Product_Queue& wq;
+* rw_mutex m;
+* {
+* rw_locking_ptr <Product_Queue, mutex> q_wlptr(wq, m);
+* // q_wlptr allows to access all the wq Product_Queue function by write locking the mutex
+* {
+* rw_demoting_ptr <const Product_Queue, mutex> q_rlptr(q_wlptr);
+* // q_rlptr allows to access all the const Product_Queue function by read locking the mutex
+* }
+* }
+
+*/
+//[locking_ptr
+template <typename T, typename Lockable=boost::mutex>
+class locking_ptr : private boost::noncopyable /*< Is not copyable >*/ {
+public:
+ typedef T value_type;
+ typedef Lockable lockable_type;
+
+ locking_ptr(volatile value_type& obj, lockable_type& mtx) /*< volatile >*/
+ : ptr_(const_cast<value_type*>(&obj)) /*< const_cast >*/
+ , mtx_(mtx)
+ { mtx_.lock(); } /*< locks on construction >*/
+ ~locking_ptr()
+ { mtx_.unlock(); } /*< unlocks on destruction >*/
+
+ /*< smart pointer related operations >*/
+ value_type& operator*()
+ { return *ptr_; }
+ value_type* operator->()
+ { return ptr_; }
+private:
+ value_type* ptr_;
+ lockable_type& mtx_;
+};
+//]
+
+//[locking_ptr_lockable_value_type
+template <typename Lockable>
+class locking_ptr_1 : private boost::noncopyable {
+public:
+ typedef Lockable value_type;
+ typedef Lockable mutex_type;
+
+ locking_ptr_1(volatile value_type& obj)
+ : ptr_(const_cast<value_type*>(&obj))
+ { ptr_->lock(); }
+ ~locking_ptr_1()
+ { ptr_->unlock(); }
+
+ value_type& operator*()
+ { return *ptr_; }
+ value_type* operator->()
+ { return ptr_; }
+private:
+ value_type* ptr_; /*< only one pointer needed >*/
+};
+//]
+
+template <typename T, typename SharableLockable>
+class sharable_locking_ptr : private boost::noncopyable {
+public:
+ typedef T value_type;
+ typedef SharableLockable mutex_type;
+
+ // Constructors/destructors
+ sharable_locking_ptr(volatile value_type& obj, mutex_type& mtx)
+ : ptr_(const_cast<value_type*>(&obj)),
+ mtx_(&mtx)
+ { mtx_->lock(); }
+ ~sharable_locking_ptr()
+ { mtx_->unlock(); }
+ // Pointer behavior
+ value_type& operator*()
+ { return *ptr_; }
+ const value_type& operator*() const
+ { return *ptr_; }
+ value_type* operator->()
+ { return ptr_; }
+ const value_type* operator->() const
+ { return ptr_; }
+private:
+ value_type* ptr_;
+ mutex_type* mtx_;
+};
+
+template <typename T, typename SharableLockable>
+class sharable_locking_ptr<const T, SharableLockable> : private boost::noncopyable {
+public:
+ typedef T value_type;
+ typedef SharableLockable mutex_type;
+
+ // Constructors/destructors
+ sharable_locking_ptr(volatile const value_type& obj, mutex_type& mtx)
+ : ptr_(const_cast<value_type*>(&obj)),
+ mtx_(&mtx)
+ { mtx_->lock_shared(); }
+ ~sharable_locking_ptr()
+ { mtx_->unlock_shared(); }
+ // Pointer behavior
+ value_type& operator*()
+ { return *ptr_; }
+ const value_type& operator*() const
+ { return *ptr_; }
+ value_type* operator->()
+ { return ptr_; }
+ const value_type* operator->() const
+ { return ptr_; }
+private:
+ value_type* ptr_;
+ mutex_type* mtx_;
+};
+#if 0
+
+template <typename T, typename MUTEX>
+class rw_locking_ptr<T, MUTEX> : private boost::noncopyable {
+public:
+ typedef const T value_type;
+ typedef MUTEX mutex_type;
+
+ // Constructors/destructors
+ locking_ptr(volatile value_type& obj, mutex_type& mtx)
+ : ptr_(const_cast<value_type*>(&obj)),
+ mtx_(&mtx)
+ { mtx_->write_lock(); }
+ ~locking_ptr()
+ { mtx_->unlock(); }
+ // Pointer behavior
+ value_type& operator*()
+ { return *ptr_; }
+ value_type* operator->()
+ { return ptr_; }
+private:
+ value_type* ptr_;
+ mutex_type* mtx_;
+};
+
+template <typename T, typename MUTEX>
+class rw_locking_ptr<const T, MUTEX> : private boost::noncopyable {
+public:
+ typedef T value_type;
+ typedef MUTEX mutex_type;
+
+ // Constructors/destructors
+ locking_ptr(volatile const value_type& obj, mutex_type& mtx)
+ : ptr_(const_cast<value_type*>(&obj)),
+ mtx_(&mtx)
+ { mtx_->read_lock(); }
+ ~locking_ptr()
+ { mtx_->unlock(); }
+ // Pointer behavior
+ const value_type& operator*()
+ { return *ptr_; }
+ const value_type* operator->()
+ { return ptr_; }
+private:
+ value_type* ptr_;
+ mutex_type* mtx_;
+};
+
+template <typename LOCKABLE>
+class locking_ptr<LOCKABLE, LOCKABLE> : private boost::noncopyable {
+public:
+ typedef LOCKABLE value_type;
+ typedef LOCKABLE mutex_type;
+
+ // Constructors/destructors
+ locking_ptr(volatile value_type& obj)
+ : ptr_(const_cast<value_type*>(&obj)),
+ { ptr_->lock(); }
+ ~locking_ptr()
+ { ptr_->unlock(); }
+ // Pointer behavior
+ value_type& operator*()
+ { return *ptr_; }
+ value_type* operator->()
+ { return ptr_; }
+private:
+ value_type* ptr_;
+};
+
+template <typename T, typename MUTEX>
+class read_locking_ptr : private boost::noncopyable {
+public:
+ typedef T value_type;
+ typedef MUTEX mutex_type;
+
+ // Constructors/destructors
+ read_locking_ptr(volatile const value_type& obj, mutex_type& mtx)
+ : ptr_(const_cast<value_type*>(&obj)),
+ mtx_(&mtx)
+ { mtx_->read_lock(); }
+ ~locking_ptr()
+ { mtx_->unlock(); }
+ // Pointer behavior
+ const value_type& operator*() const
+ { return *ptr_; }
+ const value_type* operator->() const
+ { return ptr_; }
+private:
+ const value_type* ptr_;
+ mutex_type* mtx_;
+};
+
+#endif
+}
+}
+#endif
+

Added: sandbox/synchro/boost/synchro/lockers/on_dereference_locking_ptr.hpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/boost/synchro/lockers/on_dereference_locking_ptr.hpp 2009-02-09 17:34:44 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,187 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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)
+//
+// See http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_SYNCHRO_ON_DEREFERENCE_LOCKING_PTR__HPP
+#define BOOST_SYNCHRO_ON_DEREFERENCE_LOCKING_PTR__HPP
+
+#include "boost/noncopyable.hpp"
+
+namespace boost { namespace synchro {
+
+template<typename T, typename Lockable>
+class on_dereference_locking_ptr : private boost::noncopyable
+{
+public:
+ class pointer
+ {
+ public:
+ explicit pointer(T* target, Lockable* mutex)
+ : target_(target), mutex_(mutex), locked_(false)
+ {
+ }
+ ~pointer()
+ {
+ if(locked_)
+ mutex_->unlock();
+ }
+ T *operator->()
+ {
+ mutex_->lock();
+ locked_ = true;
+ return target_;
+ }
+ private:
+ T* target_;
+ Lockable* mutex_;
+ bool locked_;
+ };
+
+ explicit on_dereference_locking_ptr(T &target, Lockable& mutex)
+ : target_(&target), mutex_(&mutex)
+ {
+ }
+ pointer operator->() const
+ {
+ return pointer(target_, mutex_);
+ }
+private:
+ T* target_;
+ Lockable* mutex_;
+};
+
+
+template<typename Lockable>
+class on_dereference_locking_ptr<Lockable,Lockable>
+{
+public:
+ class pointer
+ {
+ public:
+ explicit pointer(Lockable *target)
+ : target_(target), locked_(false)
+ {
+ }
+ ~pointer()
+ {
+ if(locked_)
+ target_->unlock();
+ }
+ Lockable *operator->()
+ {
+ target_->lock();
+ locked_ = true;
+ return target_;
+ }
+ private:
+ Lockable *target_;
+ bool locked_;
+ };
+
+ explicit on_dereference_locking_ptr(Lockable &target)
+ : target(&target)
+ {
+ }
+ pointer operator->() const
+ {
+ return pointer(target);
+ }
+private:
+ Lockable *target;
+};
+
+
+#if 0
+template<typename T, typename RW_MUTEX>
+class on_dereference_read_locking_ptr
+{
+public:
+ class pointer
+ {
+ public:
+ explicit pointer(const T* target, RW_MUTEX* mutex)
+ : target_(target), mutex_(mutex), locked(false)
+ {
+ }
+ ~pointer()
+ {
+ if(locked)
+ mutex->unlock();
+ }
+ const T *operator->() const
+ {
+ mutex->read_lock();
+ locked = true;
+ return target;
+ }
+ private:
+ const T* target_;
+ mutable T* mutex_;
+ bool locked;
+ };
+ explicit on_dereference_read_locking_ptr(const T &target, RW_MUTEX& mutex)
+ : target_(&target), mutex_(&mutex)
+ {
+ }
+ pointer operator->() const
+ {
+ return pointer(target_, mutex_);
+ }
+private:
+ const T* target_;
+ mutable T* mutex_;
+};
+
+template<typename T, typename RW_MUTEX>
+class on_dereference_write_locking_ptr
+{
+public:
+ class pointer
+ {
+ public:
+ explicit pointer(T* target, RW_MUTEX* mutex)
+ : target_(target), mutex_(mutex), locked(false)
+ {
+ }
+ ~pointer()
+ {
+ if(locked)
+ mutex->unlock();
+ }
+ T *operator->()
+ {
+ mutex->lock();
+ locked = true;
+ return target;
+ }
+ private:
+ T* target_;
+ mutable T* mutex_;
+ bool locked;
+ };
+ explicit on_dereference_write_locking_ptr(T &target, RW_MUTEX& mutex)
+ : target_(&target), mutex_(&mutex)
+ {
+ }
+ pointer operator->()
+ {
+ return pointer(target_, mutex_);
+ }
+private:
+ T* target_;
+ mutable T* mutex_;
+};
+#endif
+
+}
+}
+
+#endif
+
+

Added: sandbox/synchro/boost/synchro/lockers/priority_write.hpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/boost/synchro/lockers/priority_write.hpp 2009-02-09 17:34:44 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,411 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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)
+//
+// See http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_SYNCHRO_CONDITION_LOCKER__HPP
+#define BOOST_SYNCHRO_CONDITION_LOCKER__HPP
+
+#include <boost/synchro/lockable_concepts.hpp>
+#include <boost/thread/condition.hpp>
+#include "boost/synchro/thread/mutex.hpp"
+
+namespace boost { namespace synchro {
+
+/* Write-Priority Read/Write Locks
+
+A write-priority read/write lock provides multiple threads with simultaneous
+read-only access to a protected resource, and a single thread with write access
+to the resource while excluding reads. When a writer releases a lock, other
+waiting writers will get the lock before any waiting reader. Write-priority
+read/write locks are usually used to protect resources that are more often
+read than written.
+
+A write-priority read/write lock has the rwlock_t data type. It must be
+initialized by the rwlock_init routine. The rwlock_lock_read routine locks the
+lock for a reader (multiple readers are allowed), the rwlock_unlock_read
+routine unlocks it. The rwlock_lock_write routine locks the lock for a writer,
+the rwlock_unlock_write routine unlocks it. The proper unlocking routine (for
+the reader or for the writer) must be called.
+
+In the following example, the lock owner is not checked. As a result, any
+thread can unlock any lock. Routines, such as the pthread_mutex_trylock
+subroutine, are missing and error handling is not performed, but cancelations
+are properly handled with cleanup handlers whenever required.
+
+*/
+
+struct pririty_write_mutex {
+ struct state_data
+ {
+ int lock_count;
+ bool exclusive;
+ bool upgrade;
+ bool exclusive_waiting_blocked;
+ int waiting_writers;
+ };
+
+
+
+ state_data state;
+ boost::mutex state_change;
+ boost::condition_variable shared_cond;
+ boost::condition_variable exclusive_cond;
+ boost::condition_variable upgrade_cond;
+
+ void release_waiters()
+ {
+ exclusive_cond.notify_one();
+ shared_cond.notify_all();
+ }
+ int lock_count; /* < 0 .. held by writer */
+ /* > 0 .. held by lock_count readers */
+ /* = 0 .. held by nobody */
+ int waiting_writers; /* count of wating writers */
+public:
+ shared_mutex()
+ {
+ state_data state_={0,0,0,0};
+ state=state_;
+ }
+
+ ~shared_mutex()
+ {
+ }
+
+ void lock_shared()
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lock(state_change);
+
+ while(state.exclusive || state.exclusive_waiting_blocked)
+ {
+ shared_cond.wait(lock);
+ }
+ ++state.shared_count;
+ }
+
+ bool try_lock_shared()
+ {
+ boost::mutex::scoped_lock lock(state_change);
+
+ if(state.exclusive || state.exclusive_waiting_blocked)
+ {
+ return false;
+ }
+ else
+ {
+ ++state.shared_count;
+ return true;
+ }
+ }
+
+ bool timed_lock_shared(system_time const& timeout)
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lock(state_change);
+
+ while(state.exclusive || state.exclusive_waiting_blocked)
+ {
+ if(!shared_cond.timed_wait(lock,timeout))
+ {
+ return false;
+ }
+ }
+ ++state.shared_count;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_shared(TimeDuration const & relative_time)
+ {
+ return timed_lock_shared(get_system_time()+relative_time);
+ }
+
+ void unlock_shared()
+ {
+ boost::mutex::scoped_lock lock(state_change);
+ bool const last_reader=!--state.shared_count;
+
+ if(last_reader)
+ {
+ if(state.upgrade)
+ {
+ state.upgrade=false;
+ state.exclusive=true;
+ upgrade_cond.notify_one();
+ }
+ else
+ {
+ state.exclusive_waiting_blocked=false;
+ }
+ release_waiters();
+ }
+ }
+
+ void lock()
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lock(state_change);
+
+ while(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=true;
+ exclusive_cond.wait(lock);
+ }
+ state.exclusive=true;
+ }
+
+ bool timed_lock(system_time const& timeout)
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lock(state_change);
+
+ while(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=true;
+ if(!exclusive_cond.timed_wait(lock,timeout))
+ {
+ if(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=false;
+ exclusive_cond.notify_one();
+ return false;
+ }
+ break;
+ }
+ }
+ state.exclusive=true;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+
+ bool try_lock()
+ {
+ boost::mutex::scoped_lock lock(state_change);
+
+ if(state.shared_count || state.exclusive)
+ {
+ return false;
+ }
+ else
+ {
+ state.exclusive=true;
+ return true;
+ }
+
+ }
+
+ void unlock()
+ {
+ boost::mutex::scoped_lock lock(state_change);
+ state.exclusive=false;
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+
+ void lock_upgrade()
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lock(state_change);
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ shared_cond.wait(lock);
+ }
+ ++state.shared_count;
+ state.upgrade=true;
+ }
+
+ bool timed_lock_upgrade(system_time const& timeout)
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lock(state_change);
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ if(!shared_cond.timed_wait(lock,timeout))
+ {
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ ++state.shared_count;
+ state.upgrade=true;
+ return true;
+ }
+
+ template<typename TimeDuration>
+ bool timed_lock_upgrade(TimeDuration const & relative_time)
+ {
+ return timed_lock(get_system_time()+relative_time);
+ }
+
+ bool try_lock_upgrade()
+ {
+ boost::mutex::scoped_lock lock(state_change);
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ else
+ {
+ ++state.shared_count;
+ state.upgrade=true;
+ return true;
+ }
+ }
+
+ void unlock_upgrade()
+ {
+ boost::mutex::scoped_lock lock(state_change);
+ state.upgrade=false;
+ bool const last_reader=!--state.shared_count;
+
+ if(last_reader)
+ {
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+ }
+
+ void unlock_upgrade_and_lock()
+ {
+ boost::this_thread::disable_interruption do_not_disturb;
+ boost::mutex::scoped_lock lock(state_change);
+ --state.shared_count;
+ while(state.shared_count)
+ {
+ upgrade_cond.wait(lock);
+ }
+ state.upgrade=false;
+ state.exclusive=true;
+ }
+
+ void unlock_and_lock_upgrade()
+ {
+ boost::mutex::scoped_lock lock(state_change);
+ state.exclusive=false;
+ state.upgrade=true;
+ ++state.shared_count;
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+
+ void unlock_and_lock_shared()
+ {
+ boost::mutex::scoped_lock lock(state_change);
+ state.exclusive=false;
+ ++state.shared_count;
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+
+ void unlock_upgrade_and_lock_shared()
+ {
+ boost::mutex::scoped_lock lock(state_change);
+ state.upgrade=false;
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ }
+};
+void rwlock_init(rwlock_t *rwl)
+{
+}
+
+void waiting_reader_cleanup(void *arg)
+{
+ rwlock_t *rwl;
+
+ rwl = (rwlock_t *)arg;
+ pthread_mutex_unlock(&rwl->lock);
+}
+
+void rwlock_lock_read(rwlock_t *rwl)
+{
+ pthread_mutex_lock(&rwl->lock);
+ pthread_cleanup_push(waiting_reader_cleanup, rwl);
+ while ((rwl->lock_count < 0) && (rwl->waiting_writers))
+ pthread_cond_wait(&rwl->rcond, &rwl->lock);
+ rwl->lock_count++;
+ /*
+ * Note that the pthread_cleanup_pop subroutine will
+ * execute the waiting_reader_cleanup routine
+ */
+ pthread_cleanup_pop(1);
+}
+
+void rwlock_unlock_read(rwlock_t *rwl)
+{
+ pthread_mutex_lock(&rwl->lock);
+ rwl->lock_count--;
+ if (!rwl->lock_count)
+ pthread_cond_signal(&rwl->wcond);
+ pthread_mutex_unlock(&rwl->lock);
+}
+
+void waiting_writer_cleanup(void *arg)
+{
+ rwlock_t *rwl;
+
+ rwl = (rwlock_t *)arg;
+ rwl->waiting_writers--;
+ if ((!rwl->waiting_writers) && (rwl->lock_count >= 0))
+ /*
+ * This only happens if we have been canceled
+ */
+ pthread_cond_broadcast(&rwl->wcond);
+ pthread_mutex_unlock(&rwl->lock);
+}
+
+void rwlock_lock_write(rwlock_t *rwl)
+{
+ pthread_mutex_lock(&rwl->lock);
+ rwl->waiting_writers++;
+ pthread_cleanup_push(waiting_writer_cleanup, rwl);
+ while (rwl->lock_count)
+ pthread_cond_wait(&rwl->wcond, &rwl->lock);
+ rwl->lock_count = -1;
+ /*
+ * Note that the pthread_cleanup_pop subroutine will
+ * execute the waiting_writer_cleanup routine
+ */
+ pthread_cleanup_pop(1);
+}
+
+void rwlock_unlock_write(rwlock_t *rwl)
+{
+ pthread_mutex_lock(&rwl->lock);
+ l->lock_count = 0;
+ if (!rwl->wating_writers)
+ pthread_cond_broadcast(&rwl->rcond);
+ else
+ pthread_cond_signal(&rwl->wcond);
+ pthread_mutex_unlock(&rwl->lock);
+}
+};
+
+/*
+ * Readers are counted only. When the count reaches zero, a waiting writer may
+ * take the lock. Only one writer can hold the lock. When the lock is released
+ * by a writer, another writer is awakened, if there is one. Otherwise, all
+ * waiting readers are awakened.
+ *
+ * The locking routines are cancelable, because they call the
+ * pthread_cond_wait subroutine. Cleanup handlers are therefore registered
+ * before calling the subroutine.
+ */
+}
+}
+#endif

Added: sandbox/synchro/boost/synchro/lockers/reverse_lock.hpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/boost/synchro/lockers/reverse_lock.hpp 2009-02-09 17:34:44 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,150 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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)
+//
+// See http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_SYNCHRO_IS_STRICT_LOCKER__HPP
+#define BOOST_SYNCHRO_IS_STRICT_LOCKER__HPP
+
+#include "boost/mpl/bool.hpp"
+#include "boost/noncopyable.hpp"
+#include "boost/concept_check.hpp"
+#include "boost/synchro/lockable_traits.hpp"
+#include "boost/synchro/locker_concepts.hpp"
+//#include "boost/synchro/syntactic_lock_traits.hpp"
+
+namespace boost { namespace synchro {
+
+/**
+ */
+
+template <typename Lockable>
+class reverse_locker
+{
+ reverse_locker(Lockable& mtx): mtx_(mtx) {mtx_.unlock();}
+ ~reverse_locker() {mtx_.lock();}
+
+protected:
+ Lockable& mtx_;
+};
+
+
+/*
+ *
+ * unique_lock<mutex> lock(smtx);
+ * // ... some read operations
+ * { // non locked block
+ * reverse_lock<unique_lock<mutex> > rlock(lock);
+ * // ... some code not needing
+ * } // locked again
+ * // ...
+ */
+
+template <typename Locker>
+class reverse_lock : boost::noncopyable
+{
+// BOOST_CONCEPT_ASSERT((MovableLockConcept<Locker>));
+ typedef typename lock_error_type<typename lockable_type<Locker>::type >::type lock_error;
+
+public:
+ explicit reverse_lock(Locker& locker)
+ : locker_(locker) /*< Store reference to locker >*/
+ , tmp_locker_(locker.move()) /*< Move ownership to temporaty locker >*/
+ , was_locked_(false)
+ {
+#ifndef BOOST_SYNCHRO_REVERSE_LOCK_DONT_CHECK_OWNERSHIP /*< Define BOOST_SYNCHRO_REVERSE_LOCK_DONT_CHECK_OWNERSHIP if you don't want to check locker ownership >*/
+ if (tmp_locker_.mutex()==0) {
+ locker_=tmp_locker_.move(); /*< Rollback for coherency purposes >*/
+ throw lock_error();
+ }
+#endif
+ if (tmp_locker_) { /*< ensures it is unlocked >*/
+ tmp_locker_.unlock();
+ was_locked_=true;
+ }
+ }
+ ~reverse_lock() {
+ if (was_locked_) {
+ tmp_locker_.lock();
+ }
+ locker_=tmp_locker_.move(); /*< Move ownership to nesting locker >*/
+ }
+
+protected:
+ Locker& locker_;
+ Locker tmp_locker_;
+ bool was_locked_;
+ reverse_lock();
+};
+
+/*
+ *
+ * shared_lock<mutex> lock(smtx);
+ * // ... some read operations
+ * { // non locked block
+ * reverse_lock<shared_lock<mutex> > rlock(lock);
+ * // ... some code not needing
+ * } // locked again
+ * // ...
+ */
+
+
+
+template <typename SharableMutex>
+class exclusive_lockable_adapter
+{
+ exclusive_lockable_adapter(SharableMutex& mtx): mtx_(mtx) {}
+ ~exclusive_lockable_adapter() {}
+ void lock()
+ {mtx_.lock_shared();}
+ void unlock()
+ {mtx_.unlock_shared();}
+ bool try_lock()
+ { return mtx_.try_lock_shared();}
+
+protected:
+ SharableMutex& mtx_;
+};
+
+
+/*
+ * template <class Lockable>
+ * void f(Lokable&l) const {
+ * boos::shared_lock<Lokable> lock(smtx);
+ * // ... some read operations
+ * }
+ * // elsewhere
+ * boost::mutex mtx;
+ * //
+ * {
+ * shared_lockable_adapter smtx(mtx);
+ * f(smtx);
+ * //..
+ * }
+ *
+ */
+template <typename Lockable>
+class shared_lockable_adapter
+{
+ shared_lockable_adapter(Lockable& mtx): mtx_(mtx) {}
+ ~shared_lockable_adapter() {}
+ void lock_shared() {mtx_.lock();}
+ void unlock_shared() {mtx_.unlock();}
+ bool try_lock_shared() { return mtx_.try_lock();}
+ void lock() {mtx_.lock();}
+ void unlock() {mtx_.unlock();}
+ bool try_lock() { return mtx_.try_lock();}
+ // other functions ....
+private:
+ Lockable& mtx_;
+};
+
+}
+}
+
+#endif

Added: sandbox/synchro/boost/synchro/lockers/strict_locker.hpp
==============================================================================
--- (empty file)
+++ sandbox/synchro/boost/synchro/lockers/strict_locker.hpp 2009-02-09 17:34:44 EST (Mon, 09 Feb 2009)
@@ -0,0 +1,201 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. 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)
+//
+// See http://www.boost.org/libs/synchro for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_SYNCHRO_STRICT_LOCKER__HPP
+#define BOOST_SYNCHRO_STRICT_LOCKER__HPP
+
+#include "boost/assert.hpp"
+#include "boost/concept_check.hpp"
+#include "boost/synchro/detail/deleted_functions.hpp"
+#include "boost/mpl/bool.hpp"
+#include "boost/synchro/lockers/is_strict_locker.hpp"
+#include "boost/synchro/syntactic_lock_traits.hpp"
+#include "boost/synchro/lockable_traits.hpp"
+#include "boost/synchro/lockable_concepts.hpp"
+#include "boost/synchro/locker_concepts.hpp"
+#include "boost/thread/exceptions.hpp"
+
+namespace boost { namespace synchro {
+
+/**
+* An strict_locker is a scoped lock guard ensuring the mutex is locked on the
+* scope of the lock, by locking the mutex on construction and unlocking it on
+* destruction.
+*
+* Essentially, a strict_locker's role is only to live on the stack as an
+* automatic variable. strict_locker must adhere to a non-copy and non-alias
+* policy. strict_locker disables copying by making the copy constructor and the
+* assignment operator private. While we're at it, let's disable operator new
+* and operator delete; strict_lockers are not intended to be allocated on the
+* heap. strict_locker avoids aliasing by using a slightly less orthodox and
+* less well-known technique: disable address taking.
+*/
+
+template <typename Locker>
+struct StrictLockerConcept {
+ typedef typename lockable_type<Locker>::type lockable_type;
+ BOOST_STATIC_ASSERT((is_strict_locker<Locker>::value));
+
+ void f(Locker& l ) {
+ BOOST_ASSERT((l.is_locking(lock)));
+ }
+
+ BOOST_CONCEPT_USAGE(StrictLockerConcept) {
+ {
+// Locker l(lock);
+// BOOST_ASSERT((l));
+ }
+ }
+ lockable_type lock;
+};
+#if 0
+//[strict_locker_synopsis
+template <typename Lockable>
+class strict_locker
+ : private boost::noncopyable
+{
+public:
+ typedef Lockable lockable_type;
+ typedef typename lock_traits<lockable_type>::lock_error bad_lock;
+ typedef unspecified bool_type;
+
+ explicit strict_locker(lockable_type& obj);
+ ~strict_locker();
+
+ operator bool_type() const;
+ bool operator!() const;
+ bool owns_lock() const;
+ lockable_type* mutex() const;
+
+ BOOST_ADRESS_OF_DELETE(strict_locker)
+ BOOST_HEAP_ALLOCATION_DELETE()
+ BOOST_DEFAULT_CONSTRUCTOR_DELETE(strict_locker) /*< disable default construction >*/
+ BOOST_COPY_CONSTRUCTOR_DELETE(strict_locker) /*< disable copy construction >*/
+ BOOST_COPY_ASSIGNEMENT_DELETE(strict_locker) /*< disable copy asignement >*/
+
+private:
+ strict_locker();
+};
+//]
+#endif
+//[strict_locker
+template <typename Lockable>
+class strict_locker
+#if 0
+ : private boost::noncopyable /*< Is not copyable >*/
+#endif
+{
+
+ BOOST_CONCEPT_ASSERT((LockableConcept<Lockable>));
+public:
+ typedef Lockable lockable_type;
+ explicit strict_locker(lockable_type& obj)
+ : obj_(obj) { obj.lock(); } /*< locks on construction >*/
+ ~strict_locker() { obj_.unlock(); } /*< unlocks on destruction >*/
+
+ typedef bool (strict_locker::*bool_type)() const; /*< safe bool idiom >*/
+ operator bool_type() const { return &strict_locker::owns_lock; }
+ bool operator!() const { return false; } /*< always owned >*/
+ bool owns_lock() const { return true; }
+ const lockable_type* mutex() const { return &obj_; }
+ bool is_locking(lockable_type* l) const { return l==mutex(); } /*< strict lockers specific function >*/
+
+ /*< no possibility to unlock >*/
+
+#if 0
+private: \
+ strict_locker* operator&(); \
+public:
+#else
+
+ BOOST_ADRESS_OF_DELETE(strict_locker) /*< disable aliasing >*/
+ BOOST_HEAP_ALLOCATEION_DELETE(strict_locker) /*< disable heap allocation >*/
+ BOOST_DEFAULT_CONSTRUCTOR_DELETE(strict_locker) /*< disable default construction >*/
+ BOOST_COPY_CONSTRUCTOR_DELETE(strict_locker) /*< disable copy construction >*/
+ BOOST_COPY_ASSIGNEMENT_DELETE(strict_locker) /*< disable copy asignement >*/
+#endif
+
+private:
+ lockable_type& obj_;
+#if 0
+ strict_locker(); /*< disable default constructor >*/
+#endif
+
+
+};
+//]
+template <typename Lockable>
+struct is_strict_locker<strict_locker<Lockable> > : mpl::true_ {};
+
+/**
+ * An nested strict locker is a scoped lock guard ensuring the mutex is locked on its
+ * scope, by taking ownership of an nesting locker, and locking the mutex on construction if not already locked
+ * and restoring the ownership to the nesting locker on destruction.
+ */
+//[nested_strict_locker
+template <typename Locker >
+class nested_strict_locker
+#if 0
+ : private boost::noncopyable
+#endif
+ {
+ BOOST_CONCEPT_ASSERT((MovableLockerConcept<Locker>));
+public:
+ typedef typename lockable_type<Locker>::type lockable_type; /*< Name the lockable type locked by Locker >*/
+ typedef typename syntactic_lock_traits<lockable_type>::lock_error lock_error;
+
+ nested_strict_locker(Locker& locker)
+ : locker_(locker) /*< Store reference to locker >*/
+ , tmp_locker_(locker.move()) /*< Move ownership to temporaty locker >*/
+ {
+#ifndef BOOST_SYNCHRO_STRCIT_LOCKER_DONT_CHECK_OWNERSHIP /*< Define BOOST_SYNCHRO_EXTERNALLY_LOCKED_DONT_CHECK_OWNERSHIP if you don't want to check locker ownership >*/
+ if (tmp_locker_.mutex()==0) {
+ locker_=tmp_locker_.move(); /*< Rollback for coherency purposes >*/
+ throw lock_error();
+ }
+#endif
+ if (!tmp_locker_) tmp_locker_.lock(); /*< ensures it is locked >*/
+ }
+ ~nested_strict_locker() {
+ locker_=tmp_locker_.move(); /*< Move ownership to nesting locker >*/
+ }
+ typedef bool (nested_strict_locker::*bool_type)() const;
+ operator bool_type() const { return &nested_strict_locker::owns_lock; }
+ bool operator!() const { return false; }
+ bool owns_lock() const { return true; }
+ const lockable_type* mutex() const { return tmp_locker_.mutex(); }
+ bool is_locking(lockable_type* l) const { return l==mutex(); }
+
+#if 1
+private: \
+ nested_strict_locker* operator&(); \
+public:
+#else
+ BOOST_ADRESS_OF_DELETE(nested_strict_locker)
+ BOOST_HEAP_ALLOCATEION_DELETE(nested_strict_locker)
+ BOOST_DEFAULT_CONSTRUCTOR_DELETE(strict_locker) /*< disable default construction >*/
+ BOOST_COPY_CONSTRUCTOR_DELETE(strict_locker) /*< disable copy construction >*/
+ BOOST_COPY_ASSIGNEMENT_DELETE(strict_locker) /*< disable copy asignement >*/
+#endif
+private:
+ Locker& locker_;
+ Locker tmp_locker_;
+#if 0
+ nested_strict_locker();
+#endif
+};
+//]
+
+template <typename Locker>
+struct is_strict_locker<nested_strict_locker<Locker> > : mpl::true_ {} ;
+
+}
+}
+#endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk