summaryrefslogtreecommitdiff
path: root/boost/interprocess/sync
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess/sync')
-rw-r--r--boost/interprocess/sync/detail/common_algorithms.hpp77
-rw-r--r--boost/interprocess/sync/detail/condition_algorithm_8a.hpp127
-rw-r--r--boost/interprocess/sync/detail/condition_any_algorithm.hpp220
-rw-r--r--boost/interprocess/sync/detail/locks.hpp97
-rw-r--r--boost/interprocess/sync/file_lock.hpp102
-rw-r--r--boost/interprocess/sync/interprocess_condition.hpp74
-rw-r--r--boost/interprocess/sync/interprocess_condition_any.hpp133
-rw-r--r--boost/interprocess/sync/interprocess_mutex.hpp72
-rw-r--r--boost/interprocess/sync/interprocess_recursive_mutex.hpp16
-rw-r--r--boost/interprocess/sync/interprocess_semaphore.hpp16
-rw-r--r--boost/interprocess/sync/interprocess_sharable_mutex.hpp345
-rw-r--r--boost/interprocess/sync/interprocess_upgradable_mutex.hpp156
-rw-r--r--boost/interprocess/sync/lock_options.hpp8
-rw-r--r--boost/interprocess/sync/mutex_family.hpp4
-rw-r--r--boost/interprocess/sync/named_condition.hpp45
-rw-r--r--boost/interprocess/sync/named_condition_any.hpp151
-rw-r--r--boost/interprocess/sync/named_mutex.hpp45
-rw-r--r--boost/interprocess/sync/named_recursive_mutex.hpp28
-rw-r--r--boost/interprocess/sync/named_semaphore.hpp24
-rw-r--r--boost/interprocess/sync/named_sharable_mutex.hpp230
-rw-r--r--boost/interprocess/sync/named_upgradable_mutex.hpp61
-rw-r--r--boost/interprocess/sync/null_mutex.hpp12
-rw-r--r--boost/interprocess/sync/posix/condition.hpp25
-rw-r--r--boost/interprocess/sync/posix/mutex.hpp29
-rw-r--r--boost/interprocess/sync/posix/named_mutex.hpp24
-rw-r--r--boost/interprocess/sync/posix/named_semaphore.hpp8
-rw-r--r--boost/interprocess/sync/posix/pthread_helpers.hpp14
-rw-r--r--boost/interprocess/sync/posix/ptime_to_timespec.hpp10
-rw-r--r--boost/interprocess/sync/posix/recursive_mutex.hpp31
-rw-r--r--boost/interprocess/sync/posix/semaphore.hpp4
-rw-r--r--boost/interprocess/sync/posix/semaphore_wrapper.hpp70
-rw-r--r--boost/interprocess/sync/scoped_lock.hpp18
-rw-r--r--boost/interprocess/sync/sharable_lock.hpp22
-rw-r--r--boost/interprocess/sync/shm/named_condition.hpp235
-rw-r--r--boost/interprocess/sync/shm/named_condition_any.hpp191
-rw-r--r--boost/interprocess/sync/shm/named_creation_functor.hpp12
-rw-r--r--boost/interprocess/sync/shm/named_mutex.hpp45
-rw-r--r--boost/interprocess/sync/shm/named_recursive_mutex.hpp34
-rw-r--r--boost/interprocess/sync/shm/named_semaphore.hpp29
-rw-r--r--boost/interprocess/sync/shm/named_upgradable_mutex.hpp53
-rw-r--r--boost/interprocess/sync/spin/condition.hpp43
-rw-r--r--boost/interprocess/sync/spin/interprocess_barrier.hpp4
-rw-r--r--boost/interprocess/sync/spin/mutex.hpp43
-rw-r--r--boost/interprocess/sync/spin/recursive_mutex.hpp9
-rw-r--r--boost/interprocess/sync/spin/semaphore.hpp36
-rw-r--r--boost/interprocess/sync/spin/wait.hpp181
-rw-r--r--boost/interprocess/sync/upgradable_lock.hpp20
-rw-r--r--boost/interprocess/sync/windows/condition.hpp95
-rw-r--r--boost/interprocess/sync/windows/mutex.hpp8
-rw-r--r--boost/interprocess/sync/windows/named_condition.hpp306
-rw-r--r--boost/interprocess/sync/windows/named_condition_any.hpp240
-rw-r--r--boost/interprocess/sync/windows/named_mutex.hpp10
-rw-r--r--boost/interprocess/sync/windows/named_recursive_mutex.hpp6
-rw-r--r--boost/interprocess/sync/windows/named_semaphore.hpp10
-rw-r--r--boost/interprocess/sync/windows/named_sync.hpp20
-rw-r--r--boost/interprocess/sync/windows/recursive_mutex.hpp4
-rw-r--r--boost/interprocess/sync/windows/semaphore.hpp9
-rw-r--r--boost/interprocess/sync/windows/sync_utils.hpp32
-rw-r--r--boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp77
-rw-r--r--boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp66
-rw-r--r--boost/interprocess/sync/windows/winapi_wrapper_common.hpp93
-rw-r--r--boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp4
-rw-r--r--boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp6
-rw-r--r--boost/interprocess/sync/xsi/xsi_named_mutex.hpp26
64 files changed, 2809 insertions, 1436 deletions
diff --git a/boost/interprocess/sync/detail/common_algorithms.hpp b/boost/interprocess/sync/detail/common_algorithms.hpp
new file mode 100644
index 0000000..76d1c5c
--- /dev/null
+++ b/boost/interprocess/sync/detail/common_algorithms.hpp
@@ -0,0 +1,77 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2013. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_SYNC_DETAIL_COMMON_ALGORITHMS_HPP
+#define BOOST_INTERPROCESS_SYNC_DETAIL_COMMON_ALGORITHMS_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/sync/spin/wait.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+template<class MutexType>
+bool try_based_timed_lock(MutexType &m, const boost::posix_time::ptime &abs_time)
+{
+ //Same as lock()
+ if(abs_time == boost::posix_time::pos_infin){
+ m.lock();
+ return true;
+ }
+ //Always try to lock to achieve POSIX guarantees:
+ // "Under no circumstance shall the function fail with a timeout if the mutex
+ // can be locked immediately. The validity of the abs_timeout parameter need not
+ // be checked if the mutex can be locked immediately."
+ else if(m.try_lock()){
+ return true;
+ }
+ else{
+ spin_wait swait;
+ while(microsec_clock::universal_time() < abs_time){
+ if(m.try_lock()){
+ return true;
+ }
+ swait.yield();
+ }
+ return false;
+ }
+}
+
+template<class MutexType>
+void try_based_lock(MutexType &m)
+{
+ if(!m.try_lock()){
+ spin_wait swait;
+ do{
+ if(m.try_lock()){
+ break;
+ }
+ else{
+ swait.yield();
+ }
+ }
+ while(1);
+ }
+}
+
+} //namespace ipcdetail
+} //namespace interprocess
+} //namespace boost
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_SYNC_DETAIL_COMMON_ALGORITHMS_HPP
diff --git a/boost/interprocess/sync/detail/condition_algorithm_8a.hpp b/boost/interprocess/sync/detail/condition_algorithm_8a.hpp
index eaad671..be93af7 100644
--- a/boost/interprocess/sync/detail/condition_algorithm_8a.hpp
+++ b/boost/interprocess/sync/detail/condition_algorithm_8a.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,9 +11,14 @@
#ifndef BOOST_INTERPROCESS_DETAIL_CONDITION_ALGORITHM_8A_HPP
#define BOOST_INTERPROCESS_DETAIL_CONDITION_ALGORITHM_8A_HPP
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/sync/detail/locks.hpp>
#include <limits>
namespace boost {
@@ -161,6 +166,15 @@ namespace ipcdetail {
// mutex_type &get_mtx_unblock_lock()
// };
//
+// Must be initialized as following
+//
+// get_nwaiters_blocked() == 0
+// get_nwaiters_gone() == 0
+// get_nwaiters_to_unblock() == 0
+// get_sem_block_queue() == initial count 0
+// get_sem_block_lock() == initial count 1
+// get_mtx_unblock_lock() (unlocked)
+//
template<class ConditionMembers>
class condition_algorithm_8a
{
@@ -174,16 +188,10 @@ class condition_algorithm_8a
typedef typename ConditionMembers::mutex_type mutex_type;
typedef typename ConditionMembers::integer_type integer_type;
- // nwaiters_blocked == 0
- // nwaiters_gone() == 0
- // nwaiters_to_unblock == 0
- // sem_block_queue() == initial count 0
- // sem_block_lock() == initial count 1
- // mtx_unblock_lock (unlocked)
-
public:
- template<class InterprocessMutex>
- static bool wait (ConditionMembers &data, bool timeout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mut);
+ template<class Lock>
+ static bool wait ( ConditionMembers &data, Lock &lock
+ , bool timeout_enabled, const boost::posix_time::ptime &abs_time);
static void signal(ConditionMembers &data, bool broadcast);
};
@@ -235,9 +243,13 @@ inline void condition_algorithm_8a<ConditionMembers>::signal(ConditionMembers &d
}
template<class ConditionMembers>
-template<class InterprocessMutex>
+template<class Lock>
inline bool condition_algorithm_8a<ConditionMembers>::wait
- (ConditionMembers &data, bool tout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mtxExternal)
+ ( ConditionMembers &data
+ , Lock &lock
+ , bool tout_enabled
+ , const boost::posix_time::ptime &abs_time
+ )
{
//Initialize to avoid warnings
integer_type nsignals_was_left = 0;
@@ -247,19 +259,13 @@ inline bool condition_algorithm_8a<ConditionMembers>::wait
++data.get_nwaiters_blocked();
data.get_sem_block_lock().post();
- struct scoped_unlock
- {
- InterprocessMutex & mut;
- scoped_unlock(InterprocessMutex & m)
- : mut(m)
- { m.unlock(); }
+ //Unlock external lock and program for relock
+ lock_inverter<Lock> inverted_lock(lock);
+ scoped_lock<lock_inverter<Lock> > external_unlock(inverted_lock);
- ~scoped_unlock()
- { mut.lock(); }
- } unlocker(mtxExternal);
-
-
- bool bTimedOut = tout_enabled ? !data.get_sem_block_queue().timed_wait(abs_time) : (data.get_sem_block_queue().wait(), false);
+ bool bTimedOut = tout_enabled
+ ? !data.get_sem_block_queue().timed_wait(abs_time)
+ : (data.get_sem_block_queue().wait(), false);
{
scoped_lock<mutex_type> locker(data.get_mtx_unblock_lock());
@@ -290,7 +296,7 @@ inline bool condition_algorithm_8a<ConditionMembers>::wait
data.get_nwaiters_gone() = 0;
}
//locker's destructor triggers data.get_mtx_unblock_lock().unlock()
- }
+ }
if ( 1 == nsignals_was_left ) {
if ( 0 != nwaiters_was_gone ) {
@@ -302,11 +308,80 @@ inline bool condition_algorithm_8a<ConditionMembers>::wait
data.get_sem_block_lock().post(); // open the gate
}
- //mtxExternal.lock(); called from unlocker
+ //lock.lock(); called from unlocker destructor
return ( bTimedOut ) ? false : true;
}
+
+template<class ConditionMembers>
+class condition_8a_wrapper
+{
+ //Non-copyable
+ condition_8a_wrapper(const condition_8a_wrapper &);
+ condition_8a_wrapper &operator=(const condition_8a_wrapper &);
+
+ ConditionMembers m_data;
+ typedef ipcdetail::condition_algorithm_8a<ConditionMembers> algo_type;
+
+ public:
+
+ condition_8a_wrapper(){}
+
+ //Compiler-generated destructor is OK
+ //~condition_8a_wrapper(){}
+
+ ConditionMembers & get_members()
+ { return m_data; }
+
+ const ConditionMembers & get_members() const
+ { return m_data; }
+
+ void notify_one()
+ { algo_type::signal(m_data, false); }
+
+ void notify_all()
+ { algo_type::signal(m_data, true); }
+
+ template <typename L>
+ void wait(L& lock)
+ {
+ if (!lock)
+ throw lock_exception();
+ algo_type::wait(m_data, lock, false, boost::posix_time::ptime());
+ }
+
+ template <typename L, typename Pr>
+ void wait(L& lock, Pr pred)
+ {
+ if (!lock)
+ throw lock_exception();
+
+ while (!pred())
+ algo_type::wait(m_data, lock, false, boost::posix_time::ptime());
+ }
+
+ template <typename L>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
+ {
+ if (!lock)
+ throw lock_exception();
+ return algo_type::wait(m_data, lock, true, abs_time);
+ }
+
+ template <typename L, typename Pr>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+ {
+ if (!lock)
+ throw lock_exception();
+ while (!pred()){
+ if (!algo_type::wait(m_data, lock, true, abs_time))
+ return pred();
+ }
+ return true;
+ }
+};
+
} //namespace ipcdetail
} //namespace interprocess
} //namespace boost
diff --git a/boost/interprocess/sync/detail/condition_any_algorithm.hpp b/boost/interprocess/sync/detail/condition_any_algorithm.hpp
new file mode 100644
index 0000000..5819acf
--- /dev/null
+++ b/boost/interprocess/sync/detail/condition_any_algorithm.hpp
@@ -0,0 +1,220 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_DETAIL_CONDITION_ANY_ALGORITHM_HPP
+#define BOOST_INTERPROCESS_DETAIL_CONDITION_ANY_ALGORITHM_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/sync/detail/locks.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+//
+// Condition variable 'any' (able to use any type of external mutex)
+//
+// The code is based on Howard E. Hinnant's ISO C++ N2406 paper.
+// Many thanks to Howard for his support and comments.
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+// Required interface for ConditionAnyMembers
+// class ConditionAnyMembers
+// {
+// typedef implementation_defined mutex_type;
+// typedef implementation_defined condvar_type;
+//
+// condvar &get_condvar()
+// mutex_type &get_mutex()
+// };
+//
+// Must be initialized as following
+//
+// get_condvar() [no threads blocked]
+// get_mutex() [unlocked]
+
+template<class ConditionAnyMembers>
+class condition_any_algorithm
+{
+ private:
+ condition_any_algorithm();
+ ~condition_any_algorithm();
+ condition_any_algorithm(const condition_any_algorithm &);
+ condition_any_algorithm &operator=(const condition_any_algorithm &);
+
+ typedef typename ConditionAnyMembers::mutex_type mutex_type;
+ typedef typename ConditionAnyMembers::condvar_type condvar_type;
+
+ template <class Lock>
+ static void do_wait(ConditionAnyMembers &data, Lock& lock);
+
+ template <class Lock>
+ static bool do_timed_wait(ConditionAnyMembers &data, Lock& lock, const boost::posix_time::ptime &abs_time);
+
+ public:
+ template<class Lock>
+ static bool wait ( ConditionAnyMembers &data, Lock &mut
+ , bool timeout_enabled, const boost::posix_time::ptime &abs_time);
+ static void signal( ConditionAnyMembers &data, bool broadcast);
+};
+
+template<class ConditionAnyMembers>
+void condition_any_algorithm<ConditionAnyMembers>::signal(ConditionAnyMembers &data, bool broadcast)
+{
+ scoped_lock<mutex_type> internal_lock(data.get_mutex());
+ if(broadcast){
+ data.get_condvar().notify_all();
+ }
+ else{
+ data.get_condvar().notify_one();
+ }
+}
+
+template<class ConditionAnyMembers>
+template<class Lock>
+bool condition_any_algorithm<ConditionAnyMembers>::wait
+ ( ConditionAnyMembers &data
+ , Lock &lock
+ , bool tout_enabled
+ , const boost::posix_time::ptime &abs_time)
+{
+ if(tout_enabled){
+ return condition_any_algorithm::do_timed_wait(data, lock, abs_time);
+ }
+ else{
+ condition_any_algorithm::do_wait(data, lock);
+ return true;
+ }
+}
+
+template<class ConditionAnyMembers>
+template <class Lock>
+void condition_any_algorithm<ConditionAnyMembers>::do_wait
+ (ConditionAnyMembers &data, Lock& lock)
+{
+ //lock internal before unlocking external to avoid race with a notifier
+ scoped_lock<mutex_type> internal_lock(data.get_mutex());
+ {
+ lock_inverter<Lock> inverted_lock(lock);
+ scoped_lock<lock_inverter<Lock> > external_unlock(inverted_lock);
+ { //unlock internal first to avoid deadlock with near simultaneous waits
+ scoped_lock<mutex_type> internal_unlock;
+ internal_lock.swap(internal_unlock);
+ data.get_condvar().wait(internal_unlock);
+ }
+ }
+}
+
+template<class ConditionAnyMembers>
+template <class Lock>
+bool condition_any_algorithm<ConditionAnyMembers>::do_timed_wait
+ (ConditionAnyMembers &data, Lock& lock, const boost::posix_time::ptime &abs_time)
+{
+ //lock internal before unlocking external to avoid race with a notifier
+ scoped_lock<mutex_type> internal_lock(data.get_mutex());
+ {
+ //Unlock external lock and program for relock
+ lock_inverter<Lock> inverted_lock(lock);
+ scoped_lock<lock_inverter<Lock> > external_unlock(inverted_lock);
+ { //unlock internal first to avoid deadlock with near simultaneous waits
+ scoped_lock<mutex_type> internal_unlock;
+ internal_lock.swap(internal_unlock);
+ return data.get_condvar().timed_wait(internal_unlock, abs_time);
+ }
+ }
+}
+
+
+template<class ConditionAnyMembers>
+class condition_any_wrapper
+{
+ //Non-copyable
+ condition_any_wrapper(const condition_any_wrapper &);
+ condition_any_wrapper &operator=(const condition_any_wrapper &);
+
+ ConditionAnyMembers m_data;
+ typedef ipcdetail::condition_any_algorithm<ConditionAnyMembers> algo_type;
+
+ public:
+
+ condition_any_wrapper(){}
+
+ ~condition_any_wrapper(){}
+
+ ConditionAnyMembers & get_members()
+ { return m_data; }
+
+ const ConditionAnyMembers & get_members() const
+ { return m_data; }
+
+ void notify_one()
+ { algo_type::signal(m_data, false); }
+
+ void notify_all()
+ { algo_type::signal(m_data, true); }
+
+ template <typename L>
+ void wait(L& lock)
+ {
+ if (!lock)
+ throw lock_exception();
+ algo_type::wait(m_data, lock, false, boost::posix_time::ptime());
+ }
+
+ template <typename L, typename Pr>
+ void wait(L& lock, Pr pred)
+ {
+ if (!lock)
+ throw lock_exception();
+
+ while (!pred())
+ algo_type::wait(m_data, lock, false, boost::posix_time::ptime());
+ }
+
+ template <typename L>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
+ {
+ if (!lock)
+ throw lock_exception();
+ return algo_type::wait(m_data, lock, true, abs_time);
+ }
+
+ template <typename L, typename Pr>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+ {
+ if (!lock)
+ throw lock_exception();
+ while (!pred()){
+ if (!algo_type::wait(m_data, lock, true, abs_time))
+ return pred();
+ }
+ return true;
+ }
+};
+
+} //namespace ipcdetail
+} //namespace interprocess
+} //namespace boost
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_DETAIL_CONDITION_ANY_ALGORITHM_HPP
diff --git a/boost/interprocess/sync/detail/locks.hpp b/boost/interprocess/sync/detail/locks.hpp
new file mode 100644
index 0000000..0565200
--- /dev/null
+++ b/boost/interprocess/sync/detail/locks.hpp
@@ -0,0 +1,97 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_DETAIL_LOCKS_HPP
+#define BOOST_INTERPROCESS_DETAIL_LOCKS_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+template<class Lock>
+class internal_mutex_lock
+{
+ typedef void (internal_mutex_lock::*unspecified_bool_type)();
+ public:
+
+ typedef typename Lock::mutex_type::internal_mutex_type mutex_type;
+
+
+ internal_mutex_lock(Lock &l)
+ : l_(l)
+ {}
+
+ mutex_type* mutex() const
+ { return l_ ? &l_.mutex()->internal_mutex() : 0; }
+
+ void lock() { l_.lock(); }
+
+ void unlock() { l_.unlock(); }
+
+ operator unspecified_bool_type() const
+ { return l_ ? &internal_mutex_lock::lock : 0; }
+
+ private:
+ Lock &l_;
+};
+
+template <class Lock>
+class lock_inverter
+{
+ Lock &l_;
+ public:
+ lock_inverter(Lock &l)
+ : l_(l)
+ {}
+ void lock() { l_.unlock(); }
+ void unlock() { l_.lock(); }
+};
+
+template <class Lock>
+class lock_to_sharable
+{
+ Lock &l_;
+
+ public:
+ explicit lock_to_sharable(Lock &l)
+ : l_(l)
+ {}
+ void lock() { l_.lock_sharable(); }
+ bool try_lock(){ return l_.try_lock_sharable(); }
+ void unlock() { l_.unlock_sharable(); }
+};
+
+template <class Lock>
+class lock_to_wait
+{
+ Lock &l_;
+
+ public:
+ explicit lock_to_wait(Lock &l)
+ : l_(l)
+ {}
+ void lock() { l_.wait(); }
+ bool try_lock(){ return l_.try_wait(); }
+};
+
+} //namespace ipcdetail
+} //namespace interprocess
+} //namespace boost
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_DETAIL_LOCKS_HPP
diff --git a/boost/interprocess/sync/file_lock.hpp b/boost/interprocess/sync/file_lock.hpp
index e0f7546..e8d3903 100644
--- a/boost/interprocess/sync/file_lock.hpp
+++ b/boost/interprocess/sync/file_lock.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_FILE_LOCK_HPP
#define BOOST_INTERPROCESS_FILE_LOCK_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -21,7 +21,9 @@
#include <boost/interprocess/detail/os_file_functions.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-#include <boost/move/move.hpp>
+#include <boost/interprocess/sync/detail/common_algorithms.hpp>
+#include <boost/interprocess/sync/detail/locks.hpp>
+#include <boost/move/utility_core.hpp>
//!\file
//!Describes a class that wraps file locking capabilities.
@@ -37,10 +39,10 @@ namespace interprocess {
//!process so just use file locks to synchronize threads from different processes.
class file_lock
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
BOOST_MOVABLE_BUT_NOT_COPYABLE(file_lock)
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Constructs an empty file mapping.
@@ -64,10 +66,10 @@ class file_lock
//!After the call, "moved" does not represent any file mapping.
//!Does not throw
file_lock &operator=(BOOST_RV_REF(file_lock) moved)
- {
+ {
file_lock tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
//!Closes a file lock. Does not throw.
@@ -81,7 +83,7 @@ class file_lock
m_file_hnd = other.m_file_hnd;
other.m_file_hnd = tmp;
}
-
+
//Exclusive locking
//!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
@@ -137,66 +139,11 @@ class file_lock
//!Effects: The calling thread releases the sharable ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_sharable();
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
file_handle_t m_file_hnd;
- bool timed_acquire_file_lock
- (file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time)
- {
- //Obtain current count and target time
- boost::posix_time::ptime now = microsec_clock::universal_time();
- using namespace boost::detail;
-
- if(now >= abs_time) return false;
-
- do{
- if(!ipcdetail::try_acquire_file_lock(hnd, acquired))
- return false;
-
- if(acquired)
- return true;
- else{
- now = microsec_clock::universal_time();
-
- if(now >= abs_time){
- acquired = false;
- return true;
- }
- // relinquish current time slice
- ipcdetail::thread_yield();
- }
- }while (true);
- }
-
- bool timed_acquire_file_lock_sharable
- (file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time)
- {
- //Obtain current count and target time
- boost::posix_time::ptime now = microsec_clock::universal_time();
- using namespace boost::detail;
-
- if(now >= abs_time) return false;
-
- do{
- if(!ipcdetail::try_acquire_file_lock_sharable(hnd, acquired))
- return false;
-
- if(acquired)
- return true;
- else{
- now = microsec_clock::universal_time();
-
- if(now >= abs_time){
- acquired = false;
- return true;
- }
- // relinquish current time slice
- ipcdetail::thread_yield();
- }
- }while (true);
- }
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
inline file_lock::file_lock(const char *name)
@@ -236,18 +183,7 @@ inline bool file_lock::try_lock()
}
inline bool file_lock::timed_lock(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- bool result;
- if(!this->timed_acquire_file_lock(m_file_hnd, result, abs_time)){
- error_info err(system_error_code());
- throw interprocess_exception(err);
- }
- return result;
-}
+{ return ipcdetail::try_based_timed_lock(*this, abs_time); }
inline void file_lock::unlock()
{
@@ -277,16 +213,8 @@ inline bool file_lock::try_lock_sharable()
inline bool file_lock::timed_lock_sharable(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock_sharable();
- return true;
- }
- bool result;
- if(!this->timed_acquire_file_lock_sharable(m_file_hnd, result, abs_time)){
- error_info err(system_error_code());
- throw interprocess_exception(err);
- }
- return result;
+ ipcdetail::lock_to_sharable<file_lock> lsh(*this);
+ return ipcdetail::try_based_timed_lock(lsh, abs_time);
}
inline void file_lock::unlock_sharable()
diff --git a/boost/interprocess/sync/interprocess_condition.hpp b/boost/interprocess/sync/interprocess_condition.hpp
index 9d0bea6..19fba30 100644
--- a/boost/interprocess/sync/interprocess_condition.hpp
+++ b/boost/interprocess/sync/interprocess_condition.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,17 +11,18 @@
#ifndef BOOST_INTERPROCESS_CONDITION_HPP
#define BOOST_INTERPROCESS_CONDITION_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
+#include <boost/interprocess/sync/detail/locks.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/limits.hpp>
#include <boost/assert.hpp>
@@ -38,37 +39,49 @@
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
#endif
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
//!\file
//!Describes process-shared variables interprocess_condition class
namespace boost {
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
namespace posix_time
{ class ptime; }
+#endif //#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
namespace interprocess {
class named_condition;
//!This class is a condition variable that can be placed in shared memory or
//!memory mapped files.
+//!Destroys the object of type std::condition_variable_any
+//!
+//!Unlike std::condition_variable in C++11, it is NOT safe to invoke the destructor if all
+//!threads have been only notified. It is required that they have exited their respective wait
+//!functions.
class interprocess_condition
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
interprocess_condition(const interprocess_condition &);
interprocess_condition &operator=(const interprocess_condition &);
friend class named_condition;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
public:
//!Constructs a interprocess_condition. On error throws interprocess_exception.
- interprocess_condition(){}
+ interprocess_condition()
+ {}
//!Destroys *this
//!liberating system resources.
- ~interprocess_condition(){}
+ ~interprocess_condition()
+ {}
//!If there is a thread waiting on *this, change that
//!thread's state to ready. Otherwise there is no effect.
@@ -86,9 +99,8 @@ class interprocess_condition
template <typename L>
void wait(L& lock)
{
- if (!lock)
- throw lock_exception();
- this->do_wait(*lock.mutex());
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ m_condition.wait(internal_lock);
}
//!The same as:
@@ -96,11 +108,8 @@ class interprocess_condition
template <typename L, typename Pr>
void wait(L& lock, Pr pred)
{
- if (!lock)
- throw lock_exception();
-
- while (!pred())
- this->do_wait(*lock.mutex());
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ m_condition.wait(internal_lock, pred);
}
//!Releases the lock on the interprocess_mutex object associated with lock, blocks
@@ -111,13 +120,8 @@ class interprocess_condition
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait(lock);
- return true;
- }
- if (!lock)
- throw lock_exception();
- return this->do_timed_wait(abs_time, *lock.mutex());
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ return m_condition.timed_wait(internal_lock, abs_time);
}
//!The same as: while (!pred()) {
@@ -126,27 +130,11 @@ class interprocess_condition
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait(lock, pred);
- return true;
- }
- if (!lock)
- throw lock_exception();
- while (!pred()){
- if (!this->do_timed_wait(abs_time, *lock.mutex()))
- return pred();
- }
-
- return true;
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ return m_condition.timed_wait(internal_lock, abs_time, pred);
}
- /// @cond
-
- void do_wait(interprocess_mutex &mut)
- { m_condition.do_wait(mut.mutex); }
-
- bool do_timed_wait(const boost::posix_time::ptime &abs_time, interprocess_mutex &mut)
- { return m_condition.do_timed_wait(abs_time, mut.mutex); }
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
#if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
@@ -161,7 +149,7 @@ class interprocess_condition
#else
#error "Unknown platform for interprocess_mutex"
#endif
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
} //namespace interprocess
diff --git a/boost/interprocess/sync/interprocess_condition_any.hpp b/boost/interprocess/sync/interprocess_condition_any.hpp
new file mode 100644
index 0000000..093d69c
--- /dev/null
+++ b/boost/interprocess/sync/interprocess_condition_any.hpp
@@ -0,0 +1,133 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_CONDITION_ANY_HPP
+#define BOOST_INTERPROCESS_CONDITION_ANY_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/interprocess_mutex.hpp>
+#include <boost/interprocess/sync/interprocess_condition.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/sync/detail/condition_any_algorithm.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
+//!\file
+//!Describes process-shared variables interprocess_condition_any class
+
+namespace boost {
+
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+namespace posix_time
+{ class ptime; }
+
+#endif //#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+namespace interprocess {
+
+//!This class is a condition variable that can be placed in shared memory or
+//!memory mapped files.
+//!
+//!The interprocess_condition_any class is a generalization of interprocess_condition.
+//!Whereas interprocess_condition works only on Locks with mutex_type == interprocess_mutex
+//!interprocess_condition_any can operate on any user-defined lock that meets the BasicLockable
+//!requirements (lock()/unlock() member functions).
+//!
+//!Unlike std::condition_variable_any in C++11, it is NOT safe to invoke the destructor if all
+//!threads have been only notified. It is required that they have exited their respective wait
+//!functions.
+class interprocess_condition_any
+{
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ //Non-copyable
+ interprocess_condition_any(const interprocess_condition_any &);
+ interprocess_condition_any &operator=(const interprocess_condition_any &);
+
+ class members
+ {
+ public:
+ typedef interprocess_condition condvar_type;
+ typedef interprocess_mutex mutex_type;
+
+ condvar_type &get_condvar() { return m_cond; }
+ mutex_type &get_mutex() { return m_mut; }
+
+ private:
+ condvar_type m_cond;
+ mutex_type m_mut;
+ };
+
+ ipcdetail::condition_any_wrapper<members> m_cond;
+
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ public:
+ //!Constructs a interprocess_condition_any. On error throws interprocess_exception.
+ interprocess_condition_any(){}
+
+ //!Destroys *this
+ //!liberating system resources.
+ ~interprocess_condition_any(){}
+
+ //!If there is a thread waiting on *this, change that
+ //!thread's state to ready. Otherwise there is no effect.
+ void notify_one()
+ { m_cond.notify_one(); }
+
+ //!Change the state of all threads waiting on *this to ready.
+ //!If there are no waiting threads, notify_all() has no effect.
+ void notify_all()
+ { m_cond.notify_all(); }
+
+ //!Releases the lock on the interprocess_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), and then reacquires the lock.
+ template <typename L>
+ void wait(L& lock)
+ { m_cond.wait(lock); }
+
+ //!The same as:
+ //!while (!pred()) wait(lock)
+ template <typename L, typename Pr>
+ void wait(L& lock, Pr pred)
+ { m_cond.wait(lock, pred); }
+
+ //!Releases the lock on the interprocess_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
+ //!and then reacquires the lock.
+ //!Returns: false if time abs_time is reached, otherwise true.
+ template <typename L>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
+ { return m_cond.timed_wait(lock, abs_time); }
+
+ //!The same as: while (!pred()) {
+ //! if (!timed_wait(lock, abs_time)) return pred();
+ //! } return true;
+ template <typename L, typename Pr>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+ { return m_cond.timed_wait(lock, abs_time, pred); }
+};
+
+} //namespace interprocess
+} // namespace boost
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif // BOOST_INTERPROCESS_CONDITION_ANY_HPP
diff --git a/boost/interprocess/sync/interprocess_mutex.hpp b/boost/interprocess/sync/interprocess_mutex.hpp
index 8110c84..f4f7258 100644
--- a/boost/interprocess/sync/interprocess_mutex.hpp
+++ b/boost/interprocess/sync/interprocess_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -15,9 +15,9 @@
#ifndef BOOST_INTERPROCESS_MUTEX_HPP
#define BOOST_INTERPROCESS_MUTEX_HPP
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -50,7 +50,7 @@ class mutex_traits;
#endif
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
//!\file
//!Describes a mutex class that can be placed in memory shared by
@@ -65,12 +65,31 @@ class interprocess_condition;
//!shared between processes. Allows timed lock tries
class interprocess_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
interprocess_mutex(const interprocess_mutex &);
interprocess_mutex &operator=(const interprocess_mutex &);
friend class interprocess_condition;
- /// @endcond
+
+ public:
+ #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
+ #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION
+ typedef ipcdetail::spin_mutex internal_mutex_type;
+ private:
+ friend class ipcdetail::robust_emulation_helpers::mutex_traits<interprocess_mutex>;
+ void take_ownership(){ m_mutex.take_ownership(); }
+ public:
+ #elif defined(BOOST_INTERPROCESS_USE_POSIX)
+ #undef BOOST_INTERPROCESS_USE_POSIX
+ typedef ipcdetail::posix_mutex internal_mutex_type;
+ #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ #undef BOOST_INTERPROCESS_USE_WINDOWS
+ typedef ipcdetail::windows_mutex internal_mutex_type;
+ #else
+ #error "Unknown platform for interprocess_mutex"
+ #endif
+
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Constructor.
@@ -107,24 +126,17 @@ class interprocess_mutex
//!Effects: The calling thread releases the exclusive ownership of the mutex.
//!Throws: interprocess_exception on error.
void unlock();
- /// @cond
- private:
- #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
- #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION
- friend class ipcdetail::robust_emulation_helpers::mutex_traits<interprocess_mutex>;
- void take_ownership(){ mutex.take_ownership(); }
- ipcdetail::spin_mutex mutex;
- #elif defined(BOOST_INTERPROCESS_USE_POSIX)
- #undef BOOST_INTERPROCESS_USE_POSIX
- ipcdetail::posix_mutex mutex;
- #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
- #undef BOOST_INTERPROCESS_USE_WINDOWS
- ipcdetail::windows_mutex mutex;
- #else
- #error "Unknown platform for interprocess_mutex"
- #endif
- /// @endcond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ internal_mutex_type &internal_mutex()
+ { return m_mutex; }
+
+ const internal_mutex_type &internal_mutex() const
+ { return m_mutex; }
+
+ private:
+ internal_mutex_type m_mutex;
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
} //namespace interprocess {
@@ -144,23 +156,25 @@ inline void interprocess_mutex::lock()
boost::posix_time::ptime wait_time
= boost::posix_time::microsec_clock::universal_time()
+ boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS);
- if (!mutex.timed_lock(wait_time))
+ if (!m_mutex.timed_lock(wait_time))
{
- throw interprocess_exception(timeout_when_locking_error, "Interprocess mutex timeout when locking. Possible deadlock: owner died without unlocking?");
+ throw interprocess_exception(timeout_when_locking_error
+ , "Interprocess mutex timeout when locking. Possible deadlock: "
+ "owner died without unlocking?");
}
#else
- mutex.lock();
+ m_mutex.lock();
#endif
}
inline bool interprocess_mutex::try_lock()
-{ return mutex.try_lock(); }
+{ return m_mutex.try_lock(); }
inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
-{ return mutex.timed_lock(abs_time); }
+{ return m_mutex.timed_lock(abs_time); }
inline void interprocess_mutex::unlock()
-{ mutex.unlock(); }
+{ m_mutex.unlock(); }
} //namespace interprocess {
} //namespace boost {
diff --git a/boost/interprocess/sync/interprocess_recursive_mutex.hpp b/boost/interprocess/sync/interprocess_recursive_mutex.hpp
index 3079108..fcc0e97 100644
--- a/boost/interprocess/sync/interprocess_recursive_mutex.hpp
+++ b/boost/interprocess/sync/interprocess_recursive_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -27,9 +27,9 @@
#ifndef BOOST_INTERPROCESS_RECURSIVE_MUTEX_HPP
#define BOOST_INTERPROCESS_RECURSIVE_MUTEX_HPP
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -64,7 +64,7 @@ class mutex_traits;
#endif
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
//!\file
//!Describes interprocess_recursive_mutex and shared_recursive_try_mutex classes
@@ -77,11 +77,11 @@ namespace interprocess {
//!process. Allows timed lock tries
class interprocess_recursive_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
interprocess_recursive_mutex(const interprocess_recursive_mutex &);
interprocess_recursive_mutex &operator=(const interprocess_recursive_mutex &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Constructor.
//!Throws interprocess_exception on error.
@@ -116,7 +116,7 @@ class interprocess_recursive_mutex
//! same number of times it is locked.
//!Throws: interprocess_exception on error.
void unlock();
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
#if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
@@ -133,7 +133,7 @@ class interprocess_recursive_mutex
#else
#error "Unknown platform for interprocess_mutex"
#endif
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
} //namespace interprocess {
diff --git a/boost/interprocess/sync/interprocess_semaphore.hpp b/boost/interprocess/sync/interprocess_semaphore.hpp
index 2a2f34f..df65193 100644
--- a/boost/interprocess/sync/interprocess_semaphore.hpp
+++ b/boost/interprocess/sync/interprocess_semaphore.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,9 +11,9 @@
#ifndef BOOST_INTERPROCESS_SEMAPHORE_HPP
#define BOOST_INTERPROCESS_SEMAPHORE_HPP
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -37,7 +37,7 @@
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
#endif
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
//!\file
//!Describes a interprocess_semaphore class for inter-process synchronization
@@ -49,11 +49,11 @@ namespace interprocess {
//!shared between processes. Allows timed lock tries
class interprocess_semaphore
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
interprocess_semaphore(const interprocess_semaphore &);
interprocess_semaphore &operator=(const interprocess_semaphore &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Creates a interprocess_semaphore with the given initial count.
//!interprocess_exception if there is an error.*/
@@ -87,7 +87,7 @@ class interprocess_semaphore
//!Returns the interprocess_semaphore count
// int get_count() const;
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
#undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION
@@ -99,7 +99,7 @@ class interprocess_semaphore
#undef BOOST_INTERPROCESS_USE_POSIX
ipcdetail::posix_semaphore m_sem;
#endif //#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
} //namespace interprocess {
diff --git a/boost/interprocess/sync/interprocess_sharable_mutex.hpp b/boost/interprocess/sync/interprocess_sharable_mutex.hpp
new file mode 100644
index 0000000..fbaf22a
--- /dev/null
+++ b/boost/interprocess/sync/interprocess_sharable_mutex.hpp
@@ -0,0 +1,345 @@
+//////////////////////////////////////////////////////////////////////////////
+// Code based on Howard Hinnant's shared_mutex class
+//
+// (C) Copyright Howard Hinnant 2007-2010. Distributed under the Boost
+// Software License, Version 1.0. (see http://www.boost.org/LICENSE_1_0.txt)
+//
+// (C) Copyright Ion Gaztanaga 2005-2012. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_SHARABLE_MUTEX_HPP
+#define BOOST_INTERPROCESS_SHARABLE_MUTEX_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/interprocess_mutex.hpp>
+#include <boost/interprocess/sync/interprocess_condition.hpp>
+#include <climits>
+
+
+//!\file
+//!Describes interprocess_sharable_mutex class
+
+namespace boost {
+namespace interprocess {
+
+//!Wraps a interprocess_sharable_mutex that can be placed in shared memory and can be
+//!shared between processes. Allows timed lock tries
+class interprocess_sharable_mutex
+{
+ //Non-copyable
+ interprocess_sharable_mutex(const interprocess_sharable_mutex &);
+ interprocess_sharable_mutex &operator=(const interprocess_sharable_mutex &);
+
+ friend class interprocess_condition;
+ public:
+
+ //!Constructs the sharable lock.
+ //!Throws interprocess_exception on error.
+ interprocess_sharable_mutex();
+
+ //!Destroys the sharable lock.
+ //!Does not throw.
+ ~interprocess_sharable_mutex();
+
+ //Exclusive locking
+
+ //!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
+ //! and if another thread has exclusive or sharable ownership of
+ //! the mutex, it waits until it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
+ void lock();
+
+ //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
+ //! without waiting. If no other thread has exclusive or sharable
+ //! ownership of the mutex this succeeds.
+ //!Returns: If it can acquire exclusive ownership immediately returns true.
+ //! If it has to wait, returns false.
+ //!Throws: interprocess_exception on error.
+ bool try_lock();
+
+ //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
+ //! waiting if necessary until no other thread has exclusive or sharable
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
+ bool timed_lock(const boost::posix_time::ptime &abs_time);
+
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The calling thread releases the exclusive ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
+ void unlock();
+
+ //Sharable locking
+
+ //!Effects: The calling thread tries to obtain sharable ownership of the mutex,
+ //! and if another thread has exclusive ownership of the mutex,
+ //! waits until it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
+ void lock_sharable();
+
+ //!Effects: The calling thread tries to acquire sharable ownership of the mutex
+ //! without waiting. If no other thread has exclusive ownership
+ //! of the mutex this succeeds.
+ //!Returns: If it can acquire sharable ownership immediately returns true. If it
+ //! has to wait, returns false.
+ //!Throws: interprocess_exception on error.
+ bool try_lock_sharable();
+
+ //!Effects: The calling thread tries to acquire sharable ownership of the mutex
+ //! waiting if necessary until no other thread has exclusive
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
+ bool timed_lock_sharable(const boost::posix_time::ptime &abs_time);
+
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The calling thread releases the sharable ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
+ void unlock_sharable();
+
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ private:
+ typedef scoped_lock<interprocess_mutex> scoped_lock_t;
+
+ //Pack all the control data in a word to be able
+ //to use atomic instructions in the future
+ struct control_word_t
+ {
+ unsigned exclusive_in : 1;
+ unsigned num_shared : sizeof(unsigned)*CHAR_BIT-1;
+ } m_ctrl;
+
+ interprocess_mutex m_mut;
+ interprocess_condition m_first_gate;
+ interprocess_condition m_second_gate;
+
+ private:
+ //Rollback structures for exceptions or failure return values
+ struct exclusive_rollback
+ {
+ exclusive_rollback(control_word_t &ctrl
+ ,interprocess_condition &first_gate)
+ : mp_ctrl(&ctrl), m_first_gate(first_gate)
+ {}
+
+ void release()
+ { mp_ctrl = 0; }
+
+ ~exclusive_rollback()
+ {
+ if(mp_ctrl){
+ mp_ctrl->exclusive_in = 0;
+ m_first_gate.notify_all();
+ }
+ }
+ control_word_t *mp_ctrl;
+ interprocess_condition &m_first_gate;
+ };
+
+ template<int Dummy>
+ struct base_constants_t
+ {
+ static const unsigned max_readers
+ = ~(unsigned(1) << (sizeof(unsigned)*CHAR_BIT-1));
+ };
+ typedef base_constants_t<0> constants;
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+};
+
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+template <int Dummy>
+const unsigned interprocess_sharable_mutex::base_constants_t<Dummy>::max_readers;
+
+inline interprocess_sharable_mutex::interprocess_sharable_mutex()
+{
+ this->m_ctrl.exclusive_in = 0;
+ this->m_ctrl.num_shared = 0;
+}
+
+inline interprocess_sharable_mutex::~interprocess_sharable_mutex()
+{}
+
+inline void interprocess_sharable_mutex::lock()
+{
+ scoped_lock_t lck(m_mut);
+
+ //The exclusive lock must block in the first gate
+ //if an exclusive lock has been acquired
+ while (this->m_ctrl.exclusive_in){
+ this->m_first_gate.wait(lck);
+ }
+
+ //Mark that exclusive lock has been acquired
+ this->m_ctrl.exclusive_in = 1;
+
+ //Prepare rollback
+ exclusive_rollback rollback(this->m_ctrl, this->m_first_gate);
+
+ //Now wait until all readers are gone
+ while (this->m_ctrl.num_shared){
+ this->m_second_gate.wait(lck);
+ }
+ rollback.release();
+}
+
+inline bool interprocess_sharable_mutex::try_lock()
+{
+ scoped_lock_t lck(m_mut, try_to_lock);
+
+ //If we can't lock or any has there is any exclusive
+ //or sharable mark return false;
+ if(!lck.owns()
+ || this->m_ctrl.exclusive_in
+ || this->m_ctrl.num_shared){
+ return false;
+ }
+ this->m_ctrl.exclusive_in = 1;
+ return true;
+}
+
+inline bool interprocess_sharable_mutex::timed_lock
+ (const boost::posix_time::ptime &abs_time)
+{
+ scoped_lock_t lck(m_mut, abs_time);
+ if(!lck.owns()) return false;
+
+ //The exclusive lock must block in the first gate
+ //if an exclusive lock has been acquired
+ while (this->m_ctrl.exclusive_in){
+ //Mutexes and condvars handle just fine infinite abs_times
+ //so avoid checking it here
+ if(!this->m_first_gate.timed_wait(lck, abs_time)){
+ if(this->m_ctrl.exclusive_in){
+ return false;
+ }
+ break;
+ }
+ }
+
+ //Mark that exclusive lock has been acquired
+ this->m_ctrl.exclusive_in = 1;
+
+ //Prepare rollback
+ exclusive_rollback rollback(this->m_ctrl, this->m_first_gate);
+
+ //Now wait until all readers are gone
+ while (this->m_ctrl.num_shared){
+ //Mutexes and condvars handle just fine infinite abs_times
+ //so avoid checking it here
+ if(!this->m_second_gate.timed_wait(lck, abs_time)){
+ if(this->m_ctrl.num_shared){
+ return false;
+ }
+ break;
+ }
+ }
+ rollback.release();
+ return true;
+}
+
+inline void interprocess_sharable_mutex::unlock()
+{
+ scoped_lock_t lck(m_mut);
+ this->m_ctrl.exclusive_in = 0;
+ this->m_first_gate.notify_all();
+}
+
+//Sharable locking
+
+inline void interprocess_sharable_mutex::lock_sharable()
+{
+ scoped_lock_t lck(m_mut);
+
+ //The sharable lock must block in the first gate
+ //if an exclusive lock has been acquired
+ //or there are too many sharable locks
+ while(this->m_ctrl.exclusive_in
+ || this->m_ctrl.num_shared == constants::max_readers){
+ this->m_first_gate.wait(lck);
+ }
+
+ //Increment sharable count
+ ++this->m_ctrl.num_shared;
+}
+
+inline bool interprocess_sharable_mutex::try_lock_sharable()
+{
+ scoped_lock_t lck(m_mut, try_to_lock);
+
+ //The sharable lock must fail
+ //if an exclusive lock has been acquired
+ //or there are too many sharable locks
+ if(!lck.owns()
+ || this->m_ctrl.exclusive_in
+ || this->m_ctrl.num_shared == constants::max_readers){
+ return false;
+ }
+
+ //Increment sharable count
+ ++this->m_ctrl.num_shared;
+ return true;
+}
+
+inline bool interprocess_sharable_mutex::timed_lock_sharable
+ (const boost::posix_time::ptime &abs_time)
+{
+ scoped_lock_t lck(m_mut, abs_time);
+ if(!lck.owns()) return false;
+
+ //The sharable lock must block in the first gate
+ //if an exclusive lock has been acquired
+ //or there are too many sharable locks
+ while (this->m_ctrl.exclusive_in
+ || this->m_ctrl.num_shared == constants::max_readers){
+ //Mutexes and condvars handle just fine infinite abs_times
+ //so avoid checking it here
+ if(!this->m_first_gate.timed_wait(lck, abs_time)){
+ if(this->m_ctrl.exclusive_in
+ || this->m_ctrl.num_shared == constants::max_readers){
+ return false;
+ }
+ break;
+ }
+ }
+
+ //Increment sharable count
+ ++this->m_ctrl.num_shared;
+ return true;
+}
+
+inline void interprocess_sharable_mutex::unlock_sharable()
+{
+ scoped_lock_t lck(m_mut);
+ //Decrement sharable count
+ --this->m_ctrl.num_shared;
+ if (this->m_ctrl.num_shared == 0){
+ this->m_second_gate.notify_one();
+ }
+ //Check if there are blocked sharables because of
+ //there were too many sharables
+ else if(this->m_ctrl.num_shared == (constants::max_readers-1)){
+ this->m_first_gate.notify_all();
+ }
+}
+
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_SHARABLE_MUTEX_HPP
diff --git a/boost/interprocess/sync/interprocess_upgradable_mutex.hpp b/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
index 8d5a452..b90c71e 100644
--- a/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
+++ b/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
@@ -1,6 +1,8 @@
-//////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+// Code based on Howard Hinnant's upgrade_mutex class
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +13,7 @@
#ifndef BOOST_INTERPROCESS_UPGRADABLE_MUTEX_HPP
#define BOOST_INTERPROCESS_UPGRADABLE_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -195,7 +197,7 @@ class interprocess_upgradable_mutex
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock_upgradable();
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
typedef scoped_lock<interprocess_mutex> scoped_lock_t;
@@ -249,7 +251,7 @@ class interprocess_upgradable_mutex
if(mp_ctrl){
//Recover upgradable lock
mp_ctrl->upgradable_in = 1;
- ++mp_ctrl->num_upr_shar;
+ ++mp_ctrl->num_upr_shar;
//Execute the second half of exclusive locking
mp_ctrl->exclusive_in = 0;
}
@@ -264,10 +266,10 @@ class interprocess_upgradable_mutex
= ~(unsigned(3) << (sizeof(unsigned)*CHAR_BIT-2));
};
typedef base_constants_t<0> constants;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
template <int Dummy>
const unsigned interprocess_upgradable_mutex::base_constants_t<Dummy>::max_readers;
@@ -284,12 +286,12 @@ inline interprocess_upgradable_mutex::~interprocess_upgradable_mutex()
inline void interprocess_upgradable_mutex::lock()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//The exclusive lock must block in the first gate
//if an exclusive or upgradable lock has been acquired
while (this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in){
- this->m_first_gate.wait(lock);
+ this->m_first_gate.wait(lck);
}
//Mark that exclusive lock has been acquired
@@ -300,18 +302,18 @@ inline void interprocess_upgradable_mutex::lock()
//Now wait until all readers are gone
while (this->m_ctrl.num_upr_shar){
- this->m_second_gate.wait(lock);
+ this->m_second_gate.wait(lck);
}
rollback.release();
}
inline bool interprocess_upgradable_mutex::try_lock()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//If we can't lock or any has there is any exclusive, upgradable
//or sharable mark return false;
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.exclusive_in
|| this->m_ctrl.num_upr_shar){
return false;
@@ -323,18 +325,20 @@ inline bool interprocess_upgradable_mutex::try_lock()
inline bool interprocess_upgradable_mutex::timed_lock
(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- scoped_lock_t lock(m_mut, abs_time);
- if(!lock.owns()) return false;
+ //Mutexes and condvars handle just fine infinite abs_times
+ //so avoid checking it here
+ scoped_lock_t lck(m_mut, abs_time);
+ if(!lck.owns()) return false;
//The exclusive lock must block in the first gate
//if an exclusive or upgradable lock has been acquired
while (this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in){
- if(!this->m_first_gate.timed_wait(lock, abs_time))
- return !(this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in);
+ if(!this->m_first_gate.timed_wait(lck, abs_time)){
+ if(this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in){
+ return false;
+ }
+ break;
+ }
}
//Mark that exclusive lock has been acquired
@@ -345,8 +349,11 @@ inline bool interprocess_upgradable_mutex::timed_lock
//Now wait until all readers are gone
while (this->m_ctrl.num_upr_shar){
- if(!this->m_second_gate.timed_wait(lock, abs_time)){
- return !(this->m_ctrl.num_upr_shar);
+ if(!this->m_second_gate.timed_wait(lck, abs_time)){
+ if(this->m_ctrl.num_upr_shar){
+ return false;
+ }
+ break;
}
}
rollback.release();
@@ -355,7 +362,7 @@ inline bool interprocess_upgradable_mutex::timed_lock
inline void interprocess_upgradable_mutex::unlock()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
this->m_ctrl.exclusive_in = 0;
this->m_first_gate.notify_all();
}
@@ -364,14 +371,14 @@ inline void interprocess_upgradable_mutex::unlock()
inline void interprocess_upgradable_mutex::lock_upgradable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//The upgradable lock must block in the first gate
//if an exclusive or upgradable lock has been acquired
//or there are too many sharable locks
while(this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
- this->m_first_gate.wait(lock);
+ this->m_first_gate.wait(lck);
}
//Mark that upgradable lock has been acquired
@@ -382,12 +389,12 @@ inline void interprocess_upgradable_mutex::lock_upgradable()
inline bool interprocess_upgradable_mutex::try_lock_upgradable()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//The upgradable lock must fail
//if an exclusive or upgradable lock has been acquired
//or there are too many sharable locks
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
@@ -404,12 +411,10 @@ inline bool interprocess_upgradable_mutex::try_lock_upgradable()
inline bool interprocess_upgradable_mutex::timed_lock_upgradable
(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock_upgradable();
- return true;
- }
- scoped_lock_t lock(m_mut, abs_time);
- if(!lock.owns()) return false;
+ //Mutexes and condvars handle just fine infinite abs_times
+ //so avoid checking it here
+ scoped_lock_t lck(m_mut, abs_time);
+ if(!lck.owns()) return false;
//The upgradable lock must block in the first gate
//if an exclusive or upgradable lock has been acquired
@@ -417,10 +422,13 @@ inline bool interprocess_upgradable_mutex::timed_lock_upgradable
while(this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
- if(!this->m_first_gate.timed_wait(lock, abs_time)){
- return!(this->m_ctrl.exclusive_in
- || this->m_ctrl.upgradable_in
- || this->m_ctrl.num_upr_shar == constants::max_readers);
+ if(!this->m_first_gate.timed_wait(lck, abs_time)){
+ if((this->m_ctrl.exclusive_in
+ || this->m_ctrl.upgradable_in
+ || this->m_ctrl.num_upr_shar == constants::max_readers)){
+ return false;
+ }
+ break;
}
}
@@ -433,7 +441,7 @@ inline bool interprocess_upgradable_mutex::timed_lock_upgradable
inline void interprocess_upgradable_mutex::unlock_upgradable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Mark that upgradable lock has been acquired
//And add upgradable to the sharable count
this->m_ctrl.upgradable_in = 0;
@@ -445,14 +453,14 @@ inline void interprocess_upgradable_mutex::unlock_upgradable()
inline void interprocess_upgradable_mutex::lock_sharable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//The sharable lock must block in the first gate
//if an exclusive lock has been acquired
//or there are too many sharable locks
while(this->m_ctrl.exclusive_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
- this->m_first_gate.wait(lock);
+ this->m_first_gate.wait(lck);
}
//Increment sharable count
@@ -461,12 +469,12 @@ inline void interprocess_upgradable_mutex::lock_sharable()
inline bool interprocess_upgradable_mutex::try_lock_sharable()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//The sharable lock must fail
//if an exclusive lock has been acquired
//or there are too many sharable locks
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.exclusive_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
return false;
@@ -480,21 +488,22 @@ inline bool interprocess_upgradable_mutex::try_lock_sharable()
inline bool interprocess_upgradable_mutex::timed_lock_sharable
(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock_sharable();
- return true;
- }
- scoped_lock_t lock(m_mut, abs_time);
- if(!lock.owns()) return false;
+ //Mutexes and condvars handle just fine infinite abs_times
+ //so avoid checking it here
+ scoped_lock_t lck(m_mut, abs_time);
+ if(!lck.owns()) return false;
//The sharable lock must block in the first gate
//if an exclusive lock has been acquired
//or there are too many sharable locks
while (this->m_ctrl.exclusive_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
- if(!this->m_first_gate.timed_wait(lock, abs_time)){
- return!(this->m_ctrl.exclusive_in
- || this->m_ctrl.num_upr_shar == constants::max_readers);
+ if(!this->m_first_gate.timed_wait(lck, abs_time)){
+ if(this->m_ctrl.exclusive_in
+ || this->m_ctrl.num_upr_shar == constants::max_readers){
+ return false;
+ }
+ break;
}
}
@@ -505,7 +514,7 @@ inline bool interprocess_upgradable_mutex::timed_lock_sharable
inline void interprocess_upgradable_mutex::unlock_sharable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Decrement sharable count
--this->m_ctrl.num_upr_shar;
if (this->m_ctrl.num_upr_shar == 0){
@@ -522,7 +531,7 @@ inline void interprocess_upgradable_mutex::unlock_sharable()
inline void interprocess_upgradable_mutex::unlock_and_lock_upgradable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Unmark it as exclusive
this->m_ctrl.exclusive_in = 0;
//Mark it as upgradable
@@ -535,7 +544,7 @@ inline void interprocess_upgradable_mutex::unlock_and_lock_upgradable()
inline void interprocess_upgradable_mutex::unlock_and_lock_sharable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Unmark it as exclusive
this->m_ctrl.exclusive_in = 0;
//The sharable count should be 0 so increment it
@@ -546,7 +555,7 @@ inline void interprocess_upgradable_mutex::unlock_and_lock_sharable()
inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock_sharable()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Unmark it as upgradable (we don't have to decrement count)
this->m_ctrl.upgradable_in = 0;
//Notify readers/upgradable that they can enter
@@ -557,11 +566,11 @@ inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock_sharable()
inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock()
{
- scoped_lock_t lock(m_mut);
+ scoped_lock_t lck(m_mut);
//Simulate unlock_upgradable() without
//notifying sharables.
this->m_ctrl.upgradable_in = 0;
- --this->m_ctrl.num_upr_shar;
+ --this->m_ctrl.num_upr_shar;
//Execute the second half of exclusive locking
this->m_ctrl.exclusive_in = 1;
@@ -569,22 +578,22 @@ inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock()
upgradable_to_exclusive_rollback rollback(m_ctrl);
while (this->m_ctrl.num_upr_shar){
- this->m_second_gate.wait(lock);
+ this->m_second_gate.wait(lck);
}
rollback.release();
}
inline bool interprocess_upgradable_mutex::try_unlock_upgradable_and_lock()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//Check if there are no readers
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.num_upr_shar != 1){
return false;
}
//Now unlock upgradable and mark exclusive
this->m_ctrl.upgradable_in = 0;
- --this->m_ctrl.num_upr_shar;
+ --this->m_ctrl.num_upr_shar;
this->m_ctrl.exclusive_in = 1;
return true;
}
@@ -592,13 +601,15 @@ inline bool interprocess_upgradable_mutex::try_unlock_upgradable_and_lock()
inline bool interprocess_upgradable_mutex::timed_unlock_upgradable_and_lock
(const boost::posix_time::ptime &abs_time)
{
- scoped_lock_t lock(m_mut, abs_time);
- if(!lock.owns()) return false;
+ //Mutexes and condvars handle just fine infinite abs_times
+ //so avoid checking it here
+ scoped_lock_t lck(m_mut, abs_time);
+ if(!lck.owns()) return false;
//Simulate unlock_upgradable() without
//notifying sharables.
this->m_ctrl.upgradable_in = 0;
- --this->m_ctrl.num_upr_shar;
+ --this->m_ctrl.num_upr_shar;
//Execute the second half of exclusive locking
this->m_ctrl.exclusive_in = 1;
@@ -606,8 +617,11 @@ inline bool interprocess_upgradable_mutex::timed_unlock_upgradable_and_lock
upgradable_to_exclusive_rollback rollback(m_ctrl);
while (this->m_ctrl.num_upr_shar){
- if(!this->m_second_gate.timed_wait(lock, abs_time)){
- return !(this->m_ctrl.num_upr_shar);
+ if(!this->m_second_gate.timed_wait(lck, abs_time)){
+ if(this->m_ctrl.num_upr_shar){
+ return false;
+ }
+ break;
}
}
rollback.release();
@@ -616,11 +630,11 @@ inline bool interprocess_upgradable_mutex::timed_unlock_upgradable_and_lock
inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//If we can't lock or any has there is any exclusive, upgradable
//or sharable mark return false;
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar != 1){
@@ -633,11 +647,11 @@ inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock()
inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock_upgradable()
{
- scoped_lock_t lock(m_mut, try_to_lock);
+ scoped_lock_t lck(m_mut, try_to_lock);
//The upgradable lock must fail
//if an exclusive or upgradable lock has been acquired
- if(!lock.owns()
+ if(!lck.owns()
|| this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in){
return false;
@@ -648,7 +662,7 @@ inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock_upgradab
return true;
}
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace interprocess {
} //namespace boost {
diff --git a/boost/interprocess/sync/lock_options.hpp b/boost/interprocess/sync/lock_options.hpp
index 74f3399..7e3305b 100644
--- a/boost/interprocess/sync/lock_options.hpp
+++ b/boost/interprocess/sync/lock_options.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_LOCK_OPTIONS_HPP
#define BOOST_INTERPROCESS_LOCK_OPTIONS_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -23,9 +23,13 @@
namespace boost {
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
namespace posix_time
{ class ptime; }
+#endif //#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
namespace interprocess {
//!Type to indicate to a mutex lock constructor that must not lock the mutex.
diff --git a/boost/interprocess/sync/mutex_family.hpp b/boost/interprocess/sync/mutex_family.hpp
index b153ffe..f19805f 100644
--- a/boost/interprocess/sync/mutex_family.hpp
+++ b/boost/interprocess/sync/mutex_family.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_MUTEX_FAMILY_HPP
#define BOOST_INTERPROCESS_MUTEX_FAMILY_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
diff --git a/boost/interprocess/sync/named_condition.hpp b/boost/interprocess/sync/named_condition.hpp
index ca0205a..4f0d61e 100644
--- a/boost/interprocess/sync/named_condition.hpp
+++ b/boost/interprocess/sync/named_condition.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_NAMED_CONDITION_HPP
#define BOOST_INTERPROCESS_NAMED_CONDITION_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -22,6 +22,7 @@
#include <boost/interprocess/detail/interprocess_tester.hpp>
#include <boost/interprocess/permissions.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/detail/locks.hpp>
#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
#include <boost/interprocess/sync/windows/named_condition.hpp>
#define BOOST_INTERPROCESS_USE_WINDOWS
@@ -35,21 +36,21 @@
namespace boost {
namespace interprocess {
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
namespace ipcdetail{ class interprocess_tester; }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
//! A global condition variable that can be created by name.
//! This condition variable is designed to work with named_mutex and
//! can't be placed in shared memory or memory mapped files.
class named_condition
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
named_condition();
named_condition(const named_condition &);
named_condition &operator=(const named_condition &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Creates a global condition with a name.
//!If the condition can't be created throws interprocess_exception
@@ -113,7 +114,7 @@ class named_condition
//!Returns false on error. Never throws.
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
#if defined(BOOST_INTERPROCESS_USE_WINDOWS)
typedef ipcdetail::windows_named_condition condition_type;
@@ -125,10 +126,10 @@ class named_condition
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction()
{ ipcdetail::interprocess_tester::dont_close_on_destruction(m_cond); }
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline named_condition::~named_condition()
{}
@@ -153,26 +154,40 @@ inline void named_condition::notify_all()
template <typename L>
inline void named_condition::wait(L& lock)
-{ m_cond.wait(lock); }
+{
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ m_cond.wait(internal_lock);
+}
template <typename L, typename Pr>
inline void named_condition::wait(L& lock, Pr pred)
-{ m_cond.wait(lock, pred); }
+{
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ m_cond.wait(internal_lock, pred);
+}
template <typename L>
inline bool named_condition::timed_wait
(L& lock, const boost::posix_time::ptime &abs_time)
-{ return m_cond.timed_wait(lock, abs_time); }
+{
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ return m_cond.timed_wait(internal_lock, abs_time);
+}
template <typename L, typename Pr>
inline bool named_condition::timed_wait
(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
-{ return m_cond.timed_wait(lock, abs_time, pred); }
+{
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ return m_cond.timed_wait(internal_lock, abs_time, pred);
+}
inline bool named_condition::remove(const char *name)
-{ return condition_type::remove(name); }
+{
+ return condition_type::remove(name);
+}
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace interprocess
} //namespace boost
diff --git a/boost/interprocess/sync/named_condition_any.hpp b/boost/interprocess/sync/named_condition_any.hpp
new file mode 100644
index 0000000..5d99d22
--- /dev/null
+++ b/boost/interprocess/sync/named_condition_any.hpp
@@ -0,0 +1,151 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2012. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_NAMED_CONDITION_ANY_HPP
+#define BOOST_INTERPROCESS_NAMED_CONDITION_ANY_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
+#include <boost/interprocess/permissions.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/detail/locks.hpp>
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_condition_any.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
+#else
+ #include <boost/interprocess/sync/shm/named_condition_any.hpp>
+#endif
+
+//!\file
+//!Describes a named condition class for inter-process synchronization
+
+namespace boost {
+namespace interprocess {
+
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+namespace ipcdetail{ class interprocess_tester; }
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
+//! A global condition variable that can be created by name.
+//! This condition variable is designed to work with named_mutex and
+//! can't be placed in shared memory or memory mapped files.
+class named_condition_any
+{
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ //Non-copyable
+ named_condition_any();
+ named_condition_any(const named_condition_any &);
+ named_condition_any &operator=(const named_condition_any &);
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ public:
+ //!Creates a global condition with a name.
+ //!If the condition can't be created throws interprocess_exception
+ named_condition_any(create_only_t, const char *name, const permissions &perm = permissions())
+ : m_cond(create_only_t(), name, perm)
+ {}
+
+ //!Opens or creates a global condition with a name.
+ //!If the condition is created, this call is equivalent to
+ //!named_condition_any(create_only_t, ... )
+ //!If the condition is already created, this call is equivalent
+ //!named_condition_any(open_only_t, ... )
+ //!Does not throw
+ named_condition_any(open_or_create_t, const char *name, const permissions &perm = permissions())
+ : m_cond(open_or_create_t(), name, perm)
+ {}
+
+ //!Opens a global condition with a name if that condition is previously
+ //!created. If it is not previously created this function throws
+ //!interprocess_exception.
+ named_condition_any(open_only_t, const char *name)
+ : m_cond(open_only_t(), name)
+ {}
+
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the resource from the system
+ //!use remove().
+ ~named_condition_any()
+ {}
+
+ //!If there is a thread waiting on *this, change that
+ //!thread's state to ready. Otherwise there is no effect.*/
+ void notify_one()
+ { m_cond.notify_one(); }
+
+ //!Change the state of all threads waiting on *this to ready.
+ //!If there are no waiting threads, notify_all() has no effect.
+ void notify_all()
+ { m_cond.notify_all(); }
+
+ //!Releases the lock on the named_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), and then reacquires the lock.
+ template <typename L>
+ void wait(L& lock)
+ { return m_cond.wait(lock); }
+
+ //!The same as:
+ //!while (!pred()) wait(lock)
+ template <typename L, typename Pr>
+ void wait(L& lock, Pr pred)
+ { return m_cond.wait(lock, pred); }
+
+ //!Releases the lock on the named_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
+ //!and then reacquires the lock.
+ //!Returns: false if time abs_time is reached, otherwise true.
+ template <typename L>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
+ { return m_cond.timed_wait(lock, abs_time); }
+
+ //!The same as: while (!pred()) {
+ //! if (!timed_wait(lock, abs_time)) return pred();
+ //! } return true;
+ template <typename L, typename Pr>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+ { return m_cond.timed_wait(lock, abs_time, pred); }
+
+ //!Erases a named condition from the system.
+ //!Returns false on error. Never throws.
+ static bool remove(const char *name)
+ { return condition_any_type::remove(name); }
+
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ private:
+ #if defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ typedef ipcdetail::windows_named_condition_any condition_any_type;
+ #else
+ typedef ipcdetail::shm_named_condition_any condition_any_type;
+ #endif
+ condition_any_type m_cond;
+
+ friend class ipcdetail::interprocess_tester;
+ void dont_close_on_destruction()
+ { ipcdetail::interprocess_tester::dont_close_on_destruction(m_cond); }
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+};
+
+} //namespace interprocess
+} //namespace boost
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif // BOOST_INTERPROCESS_NAMED_CONDITION_ANY_HPP
diff --git a/boost/interprocess/sync/named_mutex.hpp b/boost/interprocess/sync/named_mutex.hpp
index c34193c..e91b1f4 100644
--- a/boost/interprocess/sync/named_mutex.hpp
+++ b/boost/interprocess/sync/named_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_NAMED_MUTEX_HPP
#define BOOST_INTERPROCESS_NAMED_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -46,17 +46,17 @@ class named_condition;
//!each process should have it's own named_mutex.
class named_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
named_mutex();
named_mutex(const named_mutex &);
named_mutex &operator=(const named_mutex &);
friend class named_condition;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
- //!Creates a global interprocess_mutex with a name.
+ //!Creates a global mutex with a name.
//!Throws interprocess_exception on error.
named_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
@@ -82,19 +82,19 @@ class named_mutex
~named_mutex();
//!Unlocks a previously locked
- //!interprocess_mutex.
+ //!mutex.
void unlock();
- //!Locks interprocess_mutex, sleeps when interprocess_mutex is already locked.
+ //!Locks the mutex, sleeps when the mutex is already locked.
//!Throws interprocess_exception if a severe error is found
void lock();
- //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
+ //!Tries to lock the mutex, returns false when the mutex
//!is already locked, returns true when success.
//!Throws interprocess_exception if a severe error is found
bool try_lock();
- //!Tries to lock the interprocess_mutex until time abs_time,
+ //!Tries to lock the the mutex until time abs_time,
//!Returns false when timeout expires, returns true when locks.
//!Throws interprocess_exception if a severe error is found
bool timed_lock(const boost::posix_time::ptime &abs_time);
@@ -103,31 +103,30 @@ class named_mutex
//!Returns false on error. Never throws.
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
+ public:
#if defined(BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES)
- typedef ipcdetail::posix_named_mutex impl_t;
- impl_t m_mut;
+ typedef ipcdetail::posix_named_mutex internal_mutex_type;
#undef BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES
#elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
- typedef ipcdetail::windows_named_mutex impl_t;
- impl_t m_mut;
+ typedef ipcdetail::windows_named_mutex internal_mutex_type;
#undef BOOST_INTERPROCESS_USE_WINDOWS
#else
- typedef ipcdetail::shm_named_mutex impl_t;
- impl_t m_mut;
- public:
- interprocess_mutex *mutex() const
- { return m_mut.mutex(); }
+ typedef ipcdetail::shm_named_mutex internal_mutex_type;
#endif
+ internal_mutex_type &internal_mutex()
+ { return m_mut; }
+
+ internal_mutex_type m_mut;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline named_mutex::named_mutex(create_only_t, const char *name, const permissions &perm)
: m_mut(create_only_t(), name, perm)
@@ -160,9 +159,9 @@ inline bool named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{ return m_mut.timed_lock(abs_time); }
inline bool named_mutex::remove(const char *name)
-{ return impl_t::remove(name); }
+{ return internal_mutex_type::remove(name); }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace interprocess {
} //namespace boost {
diff --git a/boost/interprocess/sync/named_recursive_mutex.hpp b/boost/interprocess/sync/named_recursive_mutex.hpp
index 2d4b9b2..f1f629d 100644
--- a/boost/interprocess/sync/named_recursive_mutex.hpp
+++ b/boost/interprocess/sync/named_recursive_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_NAMED_RECURSIVE_MUTEX_HPP
#define BOOST_INTERPROCESS_NAMED_RECURSIVE_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -33,21 +33,21 @@
namespace boost {
namespace interprocess {
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
namespace ipcdetail{ class interprocess_tester; }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
//!A recursive mutex with a global name, so it can be found from different
//!processes. This mutex can't be placed in shared memory, and
//!each process should have it's own named_recursive_mutex.
class named_recursive_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
named_recursive_mutex();
named_recursive_mutex(const named_recursive_mutex &);
named_recursive_mutex &operator=(const named_recursive_mutex &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Creates a global recursive_mutex with a name.
@@ -97,7 +97,7 @@ class named_recursive_mutex
//!from the system
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
@@ -110,10 +110,10 @@ class named_recursive_mutex
#endif
impl_t m_mut;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline named_recursive_mutex::~named_recursive_mutex()
{}
@@ -143,18 +143,12 @@ inline bool named_recursive_mutex::try_lock()
{ return m_mut.try_lock(); }
inline bool named_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- return m_mut.timed_lock(abs_time);
-}
+{ return m_mut.timed_lock(abs_time); }
inline bool named_recursive_mutex::remove(const char *name)
{ return impl_t::remove(name); }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace interprocess {
} //namespace boost {
diff --git a/boost/interprocess/sync/named_semaphore.hpp b/boost/interprocess/sync/named_semaphore.hpp
index 39c9096..c4a421e 100644
--- a/boost/interprocess/sync/named_semaphore.hpp
+++ b/boost/interprocess/sync/named_semaphore.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_NAMED_SEMAPHORE_HPP
#define BOOST_INTERPROCESS_NAMED_SEMAPHORE_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -44,13 +44,13 @@ namespace interprocess {
//!acknowledgment mechanisms.
class named_semaphore
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
named_semaphore();
named_semaphore(const named_semaphore &);
named_semaphore &operator=(const named_semaphore &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Creates a global semaphore with a name, and an initial count.
@@ -104,7 +104,7 @@ class named_semaphore
//!Returns false on error. Never throws.
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
@@ -118,10 +118,10 @@ class named_semaphore
typedef ipcdetail::shm_named_semaphore impl_t;
#endif
impl_t m_sem;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline named_semaphore::named_semaphore
(create_only_t, const char *name, unsigned int initialCount, const permissions &perm)
@@ -153,18 +153,12 @@ inline bool named_semaphore::try_wait()
{ return m_sem.try_wait(); }
inline bool named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait();
- return true;
- }
- return m_sem.timed_wait(abs_time);
-}
+{ return m_sem.timed_wait(abs_time); }
inline bool named_semaphore::remove(const char *name)
{ return impl_t::remove(name); }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace interprocess {
} //namespace boost {
diff --git a/boost/interprocess/sync/named_sharable_mutex.hpp b/boost/interprocess/sync/named_sharable_mutex.hpp
new file mode 100644
index 0000000..f4c0aaa
--- /dev/null
+++ b/boost/interprocess/sync/named_sharable_mutex.hpp
@@ -0,0 +1,230 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2012. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_NAMED_SHARABLE_MUTEX_HPP
+#define BOOST_INTERPROCESS_NAMED_SHARABLE_MUTEX_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
+#include <boost/interprocess/sync/interprocess_sharable_mutex.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/shm/named_creation_functor.hpp>
+#include <boost/interprocess/permissions.hpp>
+
+//!\file
+//!Describes a named sharable mutex class for inter-process synchronization
+
+namespace boost {
+namespace interprocess {
+
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+namespace ipcdetail{ class interprocess_tester; }
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
+class named_condition;
+
+//!A sharable mutex with a global name, so it can be found from different
+//!processes. This mutex can't be placed in shared memory, and
+//!each process should have it's own named sharable mutex.
+class named_sharable_mutex
+{
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ //Non-copyable
+ named_sharable_mutex();
+ named_sharable_mutex(const named_sharable_mutex &);
+ named_sharable_mutex &operator=(const named_sharable_mutex &);
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ public:
+
+ //!Creates a global sharable mutex with a name.
+ //!If the sharable mutex can't be created throws interprocess_exception
+ named_sharable_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
+
+ //!Opens or creates a global sharable mutex with a name.
+ //!If the sharable mutex is created, this call is equivalent to
+ //!named_sharable_mutex(create_only_t, ...)
+ //!If the sharable mutex is already created, this call is equivalent to
+ //!named_sharable_mutex(open_only_t, ... ).
+ named_sharable_mutex(open_or_create_t open_or_create, const char *name, const permissions &perm = permissions());
+
+ //!Opens a global sharable mutex with a name if that sharable mutex
+ //!is previously.
+ //!created. If it is not previously created this function throws
+ //!interprocess_exception.
+ named_sharable_mutex(open_only_t open_only, const char *name);
+
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the resource from the system
+ //!use remove().
+ ~named_sharable_mutex();
+
+ //Exclusive locking
+
+ //!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
+ //! and if another thread has exclusive or sharable ownership of
+ //! the mutex, it waits until it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
+ void lock();
+
+ //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
+ //! without waiting. If no other thread has exclusive or sharable
+ //! ownership of the mutex this succeeds.
+ //!Returns: If it can acquire exclusive ownership immediately returns true.
+ //! If it has to wait, returns false.
+ //!Throws: interprocess_exception on error.
+ bool try_lock();
+
+ //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
+ //! waiting if necessary until no other thread has exclusive, or sharable
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
+ bool timed_lock(const boost::posix_time::ptime &abs_time);
+
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The calling thread releases the exclusive ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
+ void unlock();
+
+ //Sharable locking
+
+ //!Effects: The calling thread tries to obtain sharable ownership of the mutex,
+ //! and if another thread has exclusive ownership of the mutex,
+ //! waits until it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
+ void lock_sharable();
+
+ //!Effects: The calling thread tries to acquire sharable ownership of the mutex
+ //! without waiting. If no other thread has exclusive ownership
+ //! of the mutex this succeeds.
+ //!Returns: If it can acquire sharable ownership immediately returns true. If it
+ //! has to wait, returns false.
+ //!Throws: interprocess_exception on error.
+ bool try_lock_sharable();
+
+ //!Effects: The calling thread tries to acquire sharable ownership of the mutex
+ //! waiting if necessary until no other thread has exclusive
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
+ bool timed_lock_sharable(const boost::posix_time::ptime &abs_time);
+
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The calling thread releases the sharable ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
+ void unlock_sharable();
+
+ //!Erases a named sharable mutex from the system.
+ //!Returns false on error. Never throws.
+ static bool remove(const char *name);
+
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ private:
+ friend class ipcdetail::interprocess_tester;
+ void dont_close_on_destruction();
+
+ interprocess_sharable_mutex *mutex() const
+ { return static_cast<interprocess_sharable_mutex*>(m_shmem.get_user_address()); }
+
+ typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> open_create_impl_t;
+ open_create_impl_t m_shmem;
+ typedef ipcdetail::named_creation_functor<interprocess_sharable_mutex> construct_func_t;
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+};
+
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+inline named_sharable_mutex::~named_sharable_mutex()
+{}
+
+inline named_sharable_mutex::named_sharable_mutex
+ (create_only_t, const char *name, const permissions &perm)
+ : m_shmem (create_only
+ ,name
+ ,sizeof(interprocess_sharable_mutex) +
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
+ ,read_write
+ ,0
+ ,construct_func_t(ipcdetail::DoCreate)
+ ,perm)
+{}
+
+inline named_sharable_mutex::named_sharable_mutex
+ (open_or_create_t, const char *name, const permissions &perm)
+ : m_shmem (open_or_create
+ ,name
+ ,sizeof(interprocess_sharable_mutex) +
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
+ ,read_write
+ ,0
+ ,construct_func_t(ipcdetail::DoOpenOrCreate)
+ ,perm)
+{}
+
+inline named_sharable_mutex::named_sharable_mutex
+ (open_only_t, const char *name)
+ : m_shmem (open_only
+ ,name
+ ,read_write
+ ,0
+ ,construct_func_t(ipcdetail::DoOpen))
+{}
+
+inline void named_sharable_mutex::dont_close_on_destruction()
+{ ipcdetail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+
+inline void named_sharable_mutex::lock()
+{ this->mutex()->lock(); }
+
+inline void named_sharable_mutex::unlock()
+{ this->mutex()->unlock(); }
+
+inline bool named_sharable_mutex::try_lock()
+{ return this->mutex()->try_lock(); }
+
+inline bool named_sharable_mutex::timed_lock
+ (const boost::posix_time::ptime &abs_time)
+{ return this->mutex()->timed_lock(abs_time); }
+
+inline void named_sharable_mutex::lock_sharable()
+{ this->mutex()->lock_sharable(); }
+
+inline void named_sharable_mutex::unlock_sharable()
+{ this->mutex()->unlock_sharable(); }
+
+inline bool named_sharable_mutex::try_lock_sharable()
+{ return this->mutex()->try_lock_sharable(); }
+
+inline bool named_sharable_mutex::timed_lock_sharable
+ (const boost::posix_time::ptime &abs_time)
+{ return this->mutex()->timed_lock_sharable(abs_time); }
+
+inline bool named_sharable_mutex::remove(const char *name)
+{ return shared_memory_object::remove(name); }
+
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_NAMED_SHARABLE_MUTEX_HPP
diff --git a/boost/interprocess/sync/named_upgradable_mutex.hpp b/boost/interprocess/sync/named_upgradable_mutex.hpp
index c45fd08..e313e72 100644
--- a/boost/interprocess/sync/named_upgradable_mutex.hpp
+++ b/boost/interprocess/sync/named_upgradable_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_named_upgradable_mutex_HPP
#define BOOST_INTERPROCESS_named_upgradable_mutex_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -32,9 +32,9 @@
namespace boost {
namespace interprocess {
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
namespace ipcdetail{ class interprocess_tester; }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
class named_condition;
@@ -43,20 +43,20 @@ class named_condition;
//!each process should have it's own named upgradable mutex.
class named_upgradable_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
named_upgradable_mutex();
named_upgradable_mutex(const named_upgradable_mutex &);
named_upgradable_mutex &operator=(const named_upgradable_mutex &);
friend class named_condition;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Creates a global upgradable mutex with a name.
//!If the upgradable mutex can't be created throws interprocess_exception
named_upgradable_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global upgradable mutex with a name, and an initial count.
+ //!Opens or creates a global upgradable mutex with a name.
//!If the upgradable mutex is created, this call is equivalent to
//!named_upgradable_mutex(create_only_t, ...)
//!If the upgradable mutex is already created, this call is equivalent to
@@ -215,13 +215,19 @@ class named_upgradable_mutex
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock();
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The thread atomically releases sharable ownership and tries to acquire
+ //! upgradable ownership. This operation will fail if there are threads with sharable
+ //! or upgradable ownership, but it will maintain sharable ownership.
+ //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
+ //!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock_upgradable();
//!Erases a named upgradable mutex from the system.
//!Returns false on error. Never throws.
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
@@ -229,12 +235,13 @@ class named_upgradable_mutex
interprocess_upgradable_mutex *mutex() const
{ return static_cast<interprocess_upgradable_mutex*>(m_shmem.get_user_address()); }
- ipcdetail::managed_open_or_create_impl<shared_memory_object> m_shmem;
+ typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> open_create_impl_t;
+ open_create_impl_t m_shmem;
typedef ipcdetail::named_creation_functor<interprocess_upgradable_mutex> construct_func_t;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline named_upgradable_mutex::~named_upgradable_mutex()
{}
@@ -244,8 +251,7 @@ inline named_upgradable_mutex::named_upgradable_mutex
: m_shmem (create_only
,name
,sizeof(interprocess_upgradable_mutex) +
- ipcdetail::managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(ipcdetail::DoCreate)
@@ -257,8 +263,7 @@ inline named_upgradable_mutex::named_upgradable_mutex
: m_shmem (open_or_create
,name
,sizeof(interprocess_upgradable_mutex) +
- ipcdetail::managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(ipcdetail::DoOpenOrCreate)
@@ -288,13 +293,7 @@ inline bool named_upgradable_mutex::try_lock()
inline bool named_upgradable_mutex::timed_lock
(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- return this->mutex()->timed_lock(abs_time);
-}
+{ return this->mutex()->timed_lock(abs_time); }
inline void named_upgradable_mutex::lock_upgradable()
{ this->mutex()->lock_upgradable(); }
@@ -307,13 +306,7 @@ inline bool named_upgradable_mutex::try_lock_upgradable()
inline bool named_upgradable_mutex::timed_lock_upgradable
(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock_upgradable();
- return true;
- }
- return this->mutex()->timed_lock_upgradable(abs_time);
-}
+{ return this->mutex()->timed_lock_upgradable(abs_time); }
inline void named_upgradable_mutex::lock_sharable()
{ this->mutex()->lock_sharable(); }
@@ -326,13 +319,7 @@ inline bool named_upgradable_mutex::try_lock_sharable()
inline bool named_upgradable_mutex::timed_lock_sharable
(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock_sharable();
- return true;
- }
- return this->mutex()->timed_lock_sharable(abs_time);
-}
+{ return this->mutex()->timed_lock_sharable(abs_time); }
inline void named_upgradable_mutex::unlock_and_lock_upgradable()
{ this->mutex()->unlock_and_lock_upgradable(); }
@@ -362,7 +349,7 @@ inline bool named_upgradable_mutex::try_unlock_sharable_and_lock_upgradable()
inline bool named_upgradable_mutex::remove(const char *name)
{ return shared_memory_object::remove(name); }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace interprocess {
} //namespace boost {
diff --git a/boost/interprocess/sync/null_mutex.hpp b/boost/interprocess/sync/null_mutex.hpp
index afe444e..16db64b 100644
--- a/boost/interprocess/sync/null_mutex.hpp
+++ b/boost/interprocess/sync/null_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_NULL_MUTEX_HPP
#define BOOST_INTERPROCESS_NULL_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -24,19 +24,23 @@
namespace boost {
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
namespace posix_time
{ class ptime; }
+#endif //#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
namespace interprocess {
//!Implements a mutex that simulates a mutex without doing any operation and
//!simulates a successful operation.
class null_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
null_mutex(const null_mutex&);
null_mutex &operator= (const null_mutex&);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Constructor.
diff --git a/boost/interprocess/sync/posix/condition.hpp b/boost/interprocess/sync/posix/condition.hpp
index 48be099..e09fe4a 100644
--- a/boost/interprocess/sync/posix/condition.hpp
+++ b/boost/interprocess/sync/posix/condition.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_POSIX_CONDITION_HPP
#define BOOST_INTERPROCESS_POSIX_CONDITION_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -19,7 +19,7 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <pthread.h>
-#include <errno.h>
+#include <errno.h>
#include <boost/interprocess/sync/posix/pthread_helpers.hpp>
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
@@ -83,12 +83,13 @@ class posix_condition
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
{
+ if (!lock)
+ throw lock_exception();
+ //Posix does not support infinity absolute time so handle it here
if(abs_time == boost::posix_time::pos_infin){
this->wait(lock);
return true;
}
- if (!lock)
- throw lock_exception();
return this->do_timed_wait(abs_time, *lock.mutex());
}
@@ -98,17 +99,17 @@ class posix_condition
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
{
+ if (!lock)
+ throw lock_exception();
+ //Posix does not support infinity absolute time so handle it here
if(abs_time == boost::posix_time::pos_infin){
this->wait(lock, pred);
return true;
}
- if (!lock)
- throw lock_exception();
while (!pred()){
if (!this->do_timed_wait(abs_time, *lock.mutex()))
return pred();
}
-
return true;
}
@@ -145,21 +146,21 @@ inline posix_condition::~posix_condition()
{
int res = 0;
res = pthread_cond_destroy(&m_condition);
- BOOST_ASSERT(res == 0);
+ BOOST_ASSERT(res == 0); (void)res;
}
inline void posix_condition::notify_one()
{
int res = 0;
res = pthread_cond_signal(&m_condition);
- BOOST_ASSERT(res == 0);
+ BOOST_ASSERT(res == 0); (void)res;
}
inline void posix_condition::notify_all()
{
int res = 0;
res = pthread_cond_broadcast(&m_condition);
- BOOST_ASSERT(res == 0);
+ BOOST_ASSERT(res == 0); (void)res;
}
inline void posix_condition::do_wait(posix_mutex &mut)
@@ -167,7 +168,7 @@ inline void posix_condition::do_wait(posix_mutex &mut)
pthread_mutex_t* pmutex = &mut.m_mut;
int res = 0;
res = pthread_cond_wait(&m_condition, pmutex);
- BOOST_ASSERT(res == 0);
+ BOOST_ASSERT(res == 0); (void)res;
}
inline bool posix_condition::do_timed_wait
diff --git a/boost/interprocess/sync/posix/mutex.hpp b/boost/interprocess/sync/posix/mutex.hpp
index 393807c..4cd4207 100644
--- a/boost/interprocess/sync/posix/mutex.hpp
+++ b/boost/interprocess/sync/posix/mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -27,7 +27,7 @@
#ifndef BOOST_INTERPROCESS_DETAIL_POSIX_MUTEX_HPP
#define BOOST_INTERPROCESS_DETAIL_POSIX_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -35,7 +35,7 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <pthread.h>
-#include <errno.h>
+#include <errno.h>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
@@ -44,6 +44,7 @@
#ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
# include <boost/interprocess/detail/os_thread_functions.hpp>
+# include <boost/interprocess/sync/detail/common_algorithms.hpp>
#endif
#include <boost/assert.hpp>
@@ -102,12 +103,12 @@ inline bool posix_mutex::try_lock()
inline bool posix_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
+ #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+ //Posix does not support infinity absolute time so handle it here
if(abs_time == boost::posix_time::pos_infin){
this->lock();
return true;
}
- #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
-
timespec ts = ptime_to_timespec(abs_time);
int res = pthread_mutex_timedlock(&m_mut, &ts);
if (res != 0 && res != ETIMEDOUT)
@@ -116,22 +117,7 @@ inline bool posix_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
#else //BOOST_INTERPROCESS_POSIX_TIMEOUTS
- //Obtain current count and target time
- boost::posix_time::ptime now = microsec_clock::universal_time();
-
- do{
- if(this->try_lock()){
- break;
- }
- now = microsec_clock::universal_time();
-
- if(now >= abs_time){
- return false;
- }
- // relinquish current time slice
- thread_yield();
- }while (true);
- return true;
+ return ipcdetail::try_based_timed_lock(*this, abs_time);
#endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS
}
@@ -140,6 +126,7 @@ inline void posix_mutex::unlock()
{
int res = 0;
res = pthread_mutex_unlock(&m_mut);
+ (void)res;
BOOST_ASSERT(res == 0);
}
diff --git a/boost/interprocess/sync/posix/named_mutex.hpp b/boost/interprocess/sync/posix/named_mutex.hpp
index 931c731..2b3be2f 100644
--- a/boost/interprocess/sync/posix/named_mutex.hpp
+++ b/boost/interprocess/sync/posix/named_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_POSIX_NAMED_MUTEX_HPP
#define BOOST_INTERPROCESS_POSIX_NAMED_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -32,13 +32,13 @@ class named_condition;
class posix_named_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
posix_named_mutex();
posix_named_mutex(const posix_named_mutex &);
posix_named_mutex &operator=(const posix_named_mutex &);
friend class named_condition;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
posix_named_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
@@ -55,16 +55,16 @@ class posix_named_mutex
bool timed_lock(const boost::posix_time::ptime &abs_time);
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class interprocess_tester;
void dont_close_on_destruction();
posix_named_semaphore m_sem;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline posix_named_mutex::posix_named_mutex(create_only_t, const char *name, const permissions &perm)
: m_sem(create_only, name, 1, perm)
@@ -94,18 +94,12 @@ inline bool posix_named_mutex::try_lock()
{ return m_sem.try_wait(); }
inline bool posix_named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- return m_sem.timed_wait(abs_time);
-}
+{ return m_sem.timed_wait(abs_time); }
inline bool posix_named_mutex::remove(const char *name)
{ return posix_named_semaphore::remove(name); }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace ipcdetail {
} //namespace interprocess {
diff --git a/boost/interprocess/sync/posix/named_semaphore.hpp b/boost/interprocess/sync/posix/named_semaphore.hpp
index f0327a4..03510e3 100644
--- a/boost/interprocess/sync/posix/named_semaphore.hpp
+++ b/boost/interprocess/sync/posix/named_semaphore.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_POSIX_NAMED_CONDITION_HPP
#define BOOST_INTERPROCESS_POSIX_NAMED_CONDITION_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -23,9 +23,9 @@
namespace boost {
namespace interprocess {
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
namespace ipcdetail{ class interprocess_tester; }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
namespace ipcdetail {
diff --git a/boost/interprocess/sync/posix/pthread_helpers.hpp b/boost/interprocess/sync/posix/pthread_helpers.hpp
index bcbc44b..ce859d7 100644
--- a/boost/interprocess/sync/posix/pthread_helpers.hpp
+++ b/boost/interprocess/sync/posix/pthread_helpers.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP
#define BOOST_INTERPROCESS_PTHREAD_HELPERS_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -19,8 +19,8 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <pthread.h>
-#include <errno.h>
-#include <boost/interprocess/exceptions.hpp>
+#include <errno.h>
+#include <boost/interprocess/exceptions.hpp>
namespace boost {
namespace interprocess {
@@ -86,7 +86,7 @@ namespace ipcdetail{
void release() {mp_mut = 0; }
- private:
+ private:
pthread_mutex_t *mp_mut;
};
@@ -105,7 +105,7 @@ namespace ipcdetail{
void release() { mp_cond = 0; }
- private:
+ private:
pthread_cond_t *mp_cond;
};
@@ -151,7 +151,7 @@ namespace ipcdetail{
void release() {mp_barrier = 0; }
- private:
+ private:
pthread_barrier_t *mp_barrier;
};
diff --git a/boost/interprocess/sync/posix/ptime_to_timespec.hpp b/boost/interprocess/sync/posix/ptime_to_timespec.hpp
index 7d78735..65993de 100644
--- a/boost/interprocess/sync/posix/ptime_to_timespec.hpp
+++ b/boost/interprocess/sync/posix/ptime_to_timespec.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,6 +11,10 @@
#ifndef BOOST_INTERPROCESS_DETAIL_PTIME_TO_TIMESPEC_HPP
#define BOOST_INTERPROCESS_DETAIL_PTIME_TO_TIMESPEC_HPP
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
namespace boost {
@@ -22,7 +26,9 @@ namespace ipcdetail {
inline timespec ptime_to_timespec (const boost::posix_time::ptime &tm)
{
const boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
- boost::posix_time::time_duration duration (tm - epoch);
+ //Avoid negative absolute times
+ boost::posix_time::time_duration duration = (tm <= epoch) ? boost::posix_time::time_duration(epoch - epoch)
+ : boost::posix_time::time_duration(tm - epoch);
timespec ts;
ts.tv_sec = duration.total_seconds();
ts.tv_nsec = duration.total_nanoseconds() % 1000000000;
diff --git a/boost/interprocess/sync/posix/recursive_mutex.hpp b/boost/interprocess/sync/posix/recursive_mutex.hpp
index 456c9a4..ccb50da 100644
--- a/boost/interprocess/sync/posix/recursive_mutex.hpp
+++ b/boost/interprocess/sync/posix/recursive_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -27,17 +27,22 @@
#ifndef BOOST_INTERPROCESS_DETAIL_POSIX_RECURSIVE_MUTEX_HPP
#define BOOST_INTERPROCESS_DETAIL_POSIX_RECURSIVE_MUTEX_HPP
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <pthread.h>
-#include <errno.h>
+#include <errno.h>
#include <boost/interprocess/sync/posix/pthread_helpers.hpp>
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/exceptions.hpp>
#ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
# include <boost/interprocess/detail/os_thread_functions.hpp>
+# include <boost/interprocess/sync/detail/common_algorithms.hpp>
#endif
#include <boost/assert.hpp>
@@ -92,11 +97,12 @@ inline bool posix_recursive_mutex::try_lock()
inline bool posix_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
+ #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+ //Posix does not support infinity absolute time so handle it here
if(abs_time == boost::posix_time::pos_infin){
this->lock();
return true;
}
- #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
timespec ts = ptime_to_timespec(abs_time);
int res = pthread_mutex_timedlock(&m_mut, &ts);
@@ -106,22 +112,7 @@ inline bool posix_recursive_mutex::timed_lock(const boost::posix_time::ptime &ab
#else //BOOST_INTERPROCESS_POSIX_TIMEOUTS
- //Obtain current count and target time
- boost::posix_time::ptime now = microsec_clock::universal_time();
-
- do{
- if(this->try_lock()){
- break;
- }
- now = microsec_clock::universal_time();
-
- if(now >= abs_time){
- return false;
- }
- // relinquish current time slice
- thread_yield();
- }while (true);
- return true;
+ return ipcdetail::try_based_timed_lock(*this, abs_time);
#endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS
}
@@ -130,7 +121,7 @@ inline void posix_recursive_mutex::unlock()
{
int res = 0;
res = pthread_mutex_unlock(&m_mut);
- BOOST_ASSERT(res == 0);
+ BOOST_ASSERT(res == 0); (void)res;
}
} //namespace ipcdetail {
diff --git a/boost/interprocess/sync/posix/semaphore.hpp b/boost/interprocess/sync/posix/semaphore.hpp
index b7f62cc..ba6a6f0 100644
--- a/boost/interprocess/sync/posix/semaphore.hpp
+++ b/boost/interprocess/sync/posix/semaphore.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_HPP
#define BOOST_INTERPROCESS_POSIX_SEMAPHORE_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
diff --git a/boost/interprocess/sync/posix/semaphore_wrapper.hpp b/boost/interprocess/sync/posix/semaphore_wrapper.hpp
index 22184cd..33f55fa 100644
--- a/boost/interprocess/sync/posix/semaphore_wrapper.hpp
+++ b/boost/interprocess/sync/posix/semaphore_wrapper.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,11 +11,15 @@
#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP
#define BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/detail/os_file_functions.hpp>
-#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
+#include <boost/interprocess/detail/shared_dir_helpers.hpp>
#include <boost/interprocess/permissions.hpp>
#include <fcntl.h> //O_CREAT, O_*...
@@ -35,6 +39,8 @@
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#else
#include <boost/interprocess/detail/os_thread_functions.hpp>
+#include <boost/interprocess/sync/detail/locks.hpp>
+#include <boost/interprocess/sync/detail/common_algorithms.hpp>
#endif
namespace boost {
@@ -49,7 +55,7 @@ inline bool semaphore_open
#ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
add_leading_slash(origname, name);
#else
- create_tmp_and_clean_old_and_get_filename(origname, name);
+ create_shared_dir_cleaning_old_and_get_filepath(origname, name);
#endif
//Create new mapping
@@ -103,7 +109,7 @@ inline bool semaphore_open
inline void semaphore_close(sem_t *handle)
{
int ret = sem_close(handle);
- if(ret != 0){
+ if(ret != 0){
BOOST_ASSERT(0);
}
}
@@ -115,7 +121,7 @@ inline bool semaphore_unlink(const char *semname)
#ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
add_leading_slash(semname, sem_str);
#else
- tmp_filename(semname, sem_str);
+ shared_filepath(semname, sem_str);
#endif
return 0 == sem_unlink(sem_str.c_str());
}
@@ -131,14 +137,15 @@ inline void semaphore_init(sem_t *handle, unsigned int initialCount)
//sem_init call is not defined, but -1 is returned on failure.
//In the future, a successful call might be required to return 0.
if(ret == -1){
- throw interprocess_exception(system_error_code());
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
}
}
inline void semaphore_destroy(sem_t *handle)
{
int ret = sem_destroy(handle);
- if(ret != 0){
+ if(ret != 0){
BOOST_ASSERT(0);
}
}
@@ -147,7 +154,8 @@ inline void semaphore_post(sem_t *handle)
{
int ret = sem_post(handle);
if(ret != 0){
- throw interprocess_exception(system_error_code());
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
}
}
@@ -155,7 +163,8 @@ inline void semaphore_wait(sem_t *handle)
{
int ret = sem_wait(handle);
if(ret != 0){
- throw interprocess_exception(system_error_code());
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
}
}
@@ -167,17 +176,39 @@ inline bool semaphore_try_wait(sem_t *handle)
if(system_error_code() == EAGAIN){
return false;
}
- throw interprocess_exception(system_error_code());
- return false;
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
}
+#ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+
+struct semaphore_wrapper_try_wrapper
+{
+ explicit semaphore_wrapper_try_wrapper(sem_t *handle)
+ : m_handle(handle)
+ {}
+
+ void wait()
+ { semaphore_wait(m_handle); }
+
+ bool try_wait()
+ { return semaphore_try_wait(m_handle); }
+
+ private:
+ sem_t *m_handle;
+};
+
+#endif
+
inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time)
{
+ #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+ //Posix does not support infinity absolute time so handle it here
if(abs_time == boost::posix_time::pos_infin){
semaphore_wait(handle);
return true;
}
- #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+
timespec tspec = ptime_to_timespec(abs_time);
for (;;){
int res = sem_timedwait(handle, &tspec);
@@ -190,17 +221,16 @@ inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &
if(system_error_code() == ETIMEDOUT){
return false;
}
- throw interprocess_exception(system_error_code());
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
}
return false;
#else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
- boost::posix_time::ptime now;
- do{
- if(semaphore_try_wait(handle))
- return true;
- thread_yield();
- }while((now = microsec_clock::universal_time()) < abs_time);
- return false;
+
+ semaphore_wrapper_try_wrapper swtw(handle);
+ ipcdetail::lock_to_wait<semaphore_wrapper_try_wrapper> lw(swtw);
+ return ipcdetail::try_based_timed_lock(lw, abs_time);
+
#endif //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
}
diff --git a/boost/interprocess/sync/scoped_lock.hpp b/boost/interprocess/sync/scoped_lock.hpp
index 61fe93e..c095530 100644
--- a/boost/interprocess/sync/scoped_lock.hpp
+++ b/boost/interprocess/sync/scoped_lock.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -16,7 +16,7 @@
#ifndef BOOST_INTERPROCESS_SCOPED_LOCK_HPP
#define BOOST_INTERPROCESS_SCOPED_LOCK_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -27,7 +27,7 @@
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility_core.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
//!\file
@@ -50,12 +50,12 @@ namespace interprocess {
template <class Mutex>
class scoped_lock
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
typedef scoped_lock<Mutex> this_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_lock)
typedef bool this_type::*unspecified_bool_type;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
typedef Mutex mutex_type;
@@ -157,7 +157,7 @@ class scoped_lock
//! a)if try_unlock_upgradable_and_lock() returns true then mutex() obtains
//! the value from upgr.release() and owns() is set to true.
//! b)if try_unlock_upgradable_and_lock() returns false then upgr is
- //! unaffected and this scoped_lock construction as the same effects as
+ //! unaffected and this scoped_lock construction as the same effects as
//! a default construction.
//! c)Else upgr.owns() is false. mutex() obtains the value from upgr.release()
//! and owns() is set to false
@@ -259,7 +259,7 @@ class scoped_lock
//! mutex after the assignment (and scop will not), but the mutex's lock
//! count will be decremented by one.
scoped_lock &operator=(BOOST_RV_REF(scoped_lock) scop)
- {
+ {
if(this->owns())
this->unlock();
m_locked = scop.owns();
@@ -357,11 +357,11 @@ class scoped_lock
std::swap(m_locked, other.m_locked);
}
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
mutex_type *mp_mutex;
bool m_locked;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
} // namespace interprocess
diff --git a/boost/interprocess/sync/sharable_lock.hpp b/boost/interprocess/sync/sharable_lock.hpp
index 9342e45..efbee6d 100644
--- a/boost/interprocess/sync/sharable_lock.hpp
+++ b/boost/interprocess/sync/sharable_lock.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -16,7 +16,7 @@
#ifndef BOOST_INTERPROCESS_SHARABLE_LOCK_HPP
#define BOOST_INTERPROCESS_SHARABLE_LOCK_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -27,7 +27,7 @@
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility_core.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
//!\file
@@ -51,13 +51,13 @@ class sharable_lock
{
public:
typedef SharableMutex mutex_type;
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
typedef sharable_lock<SharableMutex> this_type;
explicit sharable_lock(scoped_lock<mutex_type>&);
typedef bool this_type::*unspecified_bool_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(sharable_lock)
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Effects: Default constructs a sharable_lock.
@@ -189,7 +189,7 @@ class sharable_lock
//! before the assignment. In this case, this will own the mutex after the assignment
//! (and upgr will not), but the mutex's lock count will be decremented by one.
sharable_lock &operator=(BOOST_RV_REF(sharable_lock<mutex_type>) upgr)
- {
+ {
if(this->owns())
this->unlock();
m_locked = upgr.owns();
@@ -203,7 +203,7 @@ class sharable_lock
//!Notes: The sharable_lock changes from a state of not owning the
//! mutex, to owning the mutex, blocking if necessary.
void lock()
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
mp_mutex->lock_sharable();
@@ -219,7 +219,7 @@ class sharable_lock
//! mutex_type does not support try_lock_sharable(), this function will
//! fail at compile time if instantiated, but otherwise have no effect.
bool try_lock()
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
m_locked = mp_mutex->try_lock_sharable();
@@ -236,7 +236,7 @@ class sharable_lock
//! timed_lock_sharable(), this function will fail at compile time if
//! instantiated, but otherwise have no effect.
bool timed_lock(const boost::posix_time::ptime& abs_time)
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
m_locked = mp_mutex->timed_lock_sharable(abs_time);
@@ -290,11 +290,11 @@ class sharable_lock
std::swap(m_locked, other.m_locked);
}
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
mutex_type *mp_mutex;
bool m_locked;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
} // namespace interprocess
diff --git a/boost/interprocess/sync/shm/named_condition.hpp b/boost/interprocess/sync/shm/named_condition.hpp
index 9d7cd77..e2ff280 100644
--- a/boost/interprocess/sync/shm/named_condition.hpp
+++ b/boost/interprocess/sync/shm/named_condition.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_SHM_NAMED_CONDITION_HPP
#define BOOST_INTERPROCESS_SHM_NAMED_CONDITION_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -29,8 +29,11 @@
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/permissions.hpp>
#if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
-#include <boost/interprocess/sync/interprocess_mutex.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
+ #include <boost/interprocess/sync/interprocess_mutex.hpp>
+ #include <boost/interprocess/sync/scoped_lock.hpp>
+ #include <boost/interprocess/sync/detail/condition_any_algorithm.hpp>
+#else
+ #include <boost/interprocess/sync/detail/locks.hpp>
#endif
@@ -41,21 +44,21 @@ namespace boost {
namespace interprocess {
namespace ipcdetail {
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
class interprocess_tester;
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
//! A global condition variable that can be created by name.
//! This condition variable is designed to work with named_mutex and
//! can't be placed in shared memory or memory mapped files.
class shm_named_condition
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
shm_named_condition();
shm_named_condition(const shm_named_condition &);
shm_named_condition &operator=(const shm_named_condition &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Creates a global condition with a name.
//!If the condition can't be created throws interprocess_exception
@@ -119,113 +122,44 @@ class shm_named_condition
//!Returns false on error. Never throws.
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
- struct condition_holder
+ #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
+ class internal_condition_members
{
- interprocess_condition cond_;
- //If named_mutex is implemented using semaphores
- //we need to store an additional mutex
- #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
- interprocess_mutex mutex_;
- #endif
- };
+ public:
+ typedef interprocess_mutex mutex_type;
+ typedef interprocess_condition condvar_type;
- interprocess_condition *condition() const
- { return &static_cast<condition_holder*>(m_shmem.get_user_address())->cond_; }
+ condvar_type& get_condvar() { return m_cond; }
+ mutex_type& get_mutex() { return m_mtx; }
- template <class Lock>
- class lock_inverter
- {
- Lock &l_;
- public:
- lock_inverter(Lock &l)
- : l_(l)
- {}
- void lock() { l_.unlock(); }
- void unlock() { l_.lock(); }
+ private:
+ mutex_type m_mtx;
+ condvar_type m_cond;
};
- //If named mutex uses POSIX semaphores, then the shm based condition variable
- //must use it's internal lock to wait, as sem_t does not store a pthread_mutex_t
- //instance needed by pthread_mutex_cond_t
- #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
- interprocess_mutex *mutex() const
- { return &static_cast<condition_holder*>(m_shmem.get_user_address())->mutex_; }
-
- template <class Lock>
- void do_wait(Lock& lock)
- {
- //shm_named_condition only works with named_mutex
- BOOST_STATIC_ASSERT((is_convertible<typename Lock::mutex_type&, named_mutex&>::value == true));
-
- //lock internal before unlocking external to avoid race with a notifier
- scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
- lock_inverter<Lock> inverted_lock(lock);
- scoped_lock<lock_inverter<Lock> > external_unlock(inverted_lock);
-
- //unlock internal first to avoid deadlock with near simultaneous waits
- scoped_lock<interprocess_mutex> internal_unlock;
- internal_lock.swap(internal_unlock);
- this->condition()->wait(internal_unlock);
- }
-
- template <class Lock>
- bool do_timed_wait(Lock& lock, const boost::posix_time::ptime &abs_time)
- {
- //shm_named_condition only works with named_mutex
- BOOST_STATIC_ASSERT((is_convertible<typename Lock::mutex_type&, named_mutex&>::value == true));
- //lock internal before unlocking external to avoid race with a notifier
- scoped_lock<interprocess_mutex> internal_lock(*this->mutex(), abs_time);
- if(!internal_lock) return false;
- lock_inverter<Lock> inverted_lock(lock);
- scoped_lock<lock_inverter<Lock> > external_unlock(inverted_lock);
-
- //unlock internal first to avoid deadlock with near simultaneous waits
- scoped_lock<interprocess_mutex> internal_unlock;
- internal_lock.swap(internal_unlock);
- return this->condition()->timed_wait(internal_unlock, abs_time);
- }
- #else //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
- template<class Lock>
- class lock_wrapper
- {
- typedef void (lock_wrapper::*unspecified_bool_type)();
- public:
-
- typedef interprocess_mutex mutex_type;
-
- lock_wrapper(Lock &l)
- : l_(l)
- {}
-
- mutex_type* mutex() const
- { return l_.mutex()->mutex(); }
-
- void lock() { l_.lock(); }
-
- void unlock() { l_.unlock(); }
-
- operator unspecified_bool_type() const
- { return l_ ? &lock_wrapper::lock : 0; }
-
- private:
- Lock &l_;
- };
+ typedef ipcdetail::condition_any_wrapper<internal_condition_members> internal_condition;
+ #else //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
+ typedef interprocess_condition internal_condition;
#endif //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
+ internal_condition &internal_cond()
+ { return *static_cast<internal_condition*>(m_shmem.get_user_address()); }
+
friend class boost::interprocess::ipcdetail::interprocess_tester;
void dont_close_on_destruction();
- managed_open_or_create_impl<shared_memory_object> m_shmem;
+ typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> open_create_impl_t;
+ open_create_impl_t m_shmem;
template <class T, class Arg> friend class boost::interprocess::ipcdetail::named_creation_functor;
- typedef boost::interprocess::ipcdetail::named_creation_functor<condition_holder> construct_func_t;
- /// @endcond
+ typedef boost::interprocess::ipcdetail::named_creation_functor<internal_condition> construct_func_t;
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline shm_named_condition::~shm_named_condition()
{}
@@ -233,9 +167,8 @@ inline shm_named_condition::~shm_named_condition()
inline shm_named_condition::shm_named_condition(create_only_t, const char *name, const permissions &perm)
: m_shmem (create_only
,name
- ,sizeof(condition_holder) +
- managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ ,sizeof(internal_condition) +
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(DoCreate)
@@ -245,9 +178,8 @@ inline shm_named_condition::shm_named_condition(create_only_t, const char *name,
inline shm_named_condition::shm_named_condition(open_or_create_t, const char *name, const permissions &perm)
: m_shmem (open_or_create
,name
- ,sizeof(condition_holder) +
- managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ ,sizeof(internal_condition) +
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(DoOpenOrCreate)
@@ -265,113 +197,34 @@ inline shm_named_condition::shm_named_condition(open_only_t, const char *name)
inline void shm_named_condition::dont_close_on_destruction()
{ interprocess_tester::dont_close_on_destruction(m_shmem); }
-#if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
-
inline void shm_named_condition::notify_one()
-{
- scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
- this->condition()->notify_one();
-}
+{ this->internal_cond().notify_one(); }
inline void shm_named_condition::notify_all()
-{
- scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
- this->condition()->notify_all();
-}
+{ this->internal_cond().notify_all(); }
template <typename L>
inline void shm_named_condition::wait(L& lock)
-{
- if (!lock)
- throw lock_exception();
- this->do_wait(lock);
-}
+{ this->internal_cond().wait(lock); }
template <typename L, typename Pr>
inline void shm_named_condition::wait(L& lock, Pr pred)
-{
- if (!lock)
- throw lock_exception();
- while (!pred())
- this->do_wait(lock);
-}
+{ this->internal_cond().wait(lock, pred); }
template <typename L>
inline bool shm_named_condition::timed_wait
(L& lock, const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait(lock);
- return true;
- }
- if (!lock)
- throw lock_exception();
- return this->do_timed_wait(lock, abs_time);
-}
+{ return this->internal_cond().timed_wait(lock, abs_time); }
template <typename L, typename Pr>
inline bool shm_named_condition::timed_wait
(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait(lock, pred);
- return true;
- }
- if (!lock)
- throw lock_exception();
-
- while (!pred()){
- if(!this->do_timed_wait(lock, abs_time)){
- return pred();
- }
- }
- return true;
-}
-
-#else
-
-inline void shm_named_condition::notify_one()
-{ this->condition()->notify_one(); }
-
-inline void shm_named_condition::notify_all()
-{ this->condition()->notify_all(); }
-
-template <typename L>
-inline void shm_named_condition::wait(L& lock)
-{
- lock_wrapper<L> newlock(lock);
- this->condition()->wait(newlock);
-}
-
-template <typename L, typename Pr>
-inline void shm_named_condition::wait(L& lock, Pr pred)
-{
- lock_wrapper<L> newlock(lock);
- this->condition()->wait(newlock, pred);
-}
-
-template <typename L>
-inline bool shm_named_condition::timed_wait
- (L& lock, const boost::posix_time::ptime &abs_time)
-{
- lock_wrapper<L> newlock(lock);
- return this->condition()->timed_wait(newlock, abs_time);
-}
-
-template <typename L, typename Pr>
-inline bool shm_named_condition::timed_wait
- (L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
-{
- lock_wrapper<L> newlock(lock);
- return this->condition()->timed_wait(newlock, abs_time, pred);
-}
-
-#endif
+{ return this->internal_cond().timed_wait(lock, abs_time, pred); }
inline bool shm_named_condition::remove(const char *name)
{ return shared_memory_object::remove(name); }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace ipcdetail
} //namespace interprocess
diff --git a/boost/interprocess/sync/shm/named_condition_any.hpp b/boost/interprocess/sync/shm/named_condition_any.hpp
new file mode 100644
index 0000000..46bca92
--- /dev/null
+++ b/boost/interprocess/sync/shm/named_condition_any.hpp
@@ -0,0 +1,191 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2012. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_SHM_NAMED_CONDITION_ANY_HPP
+#define BOOST_INTERPROCESS_SHM_NAMED_CONDITION_ANY_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/sync/interprocess_condition.hpp>
+#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/shm/named_creation_functor.hpp>
+#include <boost/interprocess/sync/named_mutex.hpp>
+#include <boost/interprocess/permissions.hpp>
+#include <boost/interprocess/sync/interprocess_mutex.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/sync/detail/condition_any_algorithm.hpp>
+
+//!\file
+//!Describes process-shared variables interprocess_condition class
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+class interprocess_tester;
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
+//! A global condition variable that can be created by name.
+//! This condition variable is designed to work with named_mutex and
+//! can't be placed in shared memory or memory mapped files.
+class shm_named_condition_any
+{
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ //Non-copyable
+ shm_named_condition_any();
+ shm_named_condition_any(const shm_named_condition_any &);
+ shm_named_condition_any &operator=(const shm_named_condition_any &);
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ public:
+ //!Creates a global condition with a name.
+ //!If the condition can't be created throws interprocess_exception
+ shm_named_condition_any(create_only_t create_only, const char *name, const permissions &perm = permissions())
+ : m_shmem (create_only
+ ,name
+ ,sizeof(internal_condition) +
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
+ ,read_write
+ ,0
+ ,construct_func_t(DoCreate)
+ ,perm)
+ {}
+
+ //!Opens or creates a global condition with a name.
+ //!If the condition is created, this call is equivalent to
+ //!shm_named_condition_any(create_only_t, ... )
+ //!If the condition is already created, this call is equivalent
+ //!shm_named_condition_any(open_only_t, ... )
+ //!Does not throw
+ shm_named_condition_any(open_or_create_t open_or_create, const char *name, const permissions &perm = permissions())
+ : m_shmem (open_or_create
+ ,name
+ ,sizeof(internal_condition) +
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
+ ,read_write
+ ,0
+ ,construct_func_t(DoOpenOrCreate)
+ ,perm)
+ {}
+
+ //!Opens a global condition with a name if that condition is previously
+ //!created. If it is not previously created this function throws
+ //!interprocess_exception.
+ shm_named_condition_any(open_only_t open_only, const char *name)
+ : m_shmem (open_only
+ ,name
+ ,read_write
+ ,0
+ ,construct_func_t(DoOpen))
+ {}
+
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the resource from the system
+ //!use remove().
+ ~shm_named_condition_any()
+ {}
+
+ //!If there is a thread waiting on *this, change that
+ //!thread's state to ready. Otherwise there is no effect.*/
+ void notify_one()
+ { m_cond.notify_one(); }
+
+ //!Change the state of all threads waiting on *this to ready.
+ //!If there are no waiting threads, notify_all() has no effect.
+ void notify_all()
+ { m_cond.notify_all(); }
+
+ //!Releases the lock on the named_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), and then reacquires the lock.
+ template <typename L>
+ void wait(L& lock)
+ { m_cond.wait(lock); }
+
+ //!The same as:
+ //!while (!pred()) wait(lock)
+ template <typename L, typename Pr>
+ void wait(L& lock, Pr pred)
+ { m_cond.wait(lock, pred); }
+
+ //!Releases the lock on the named_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
+ //!and then reacquires the lock.
+ //!Returns: false if time abs_time is reached, otherwise true.
+ template <typename L>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
+ { return m_cond.timed_wait(lock, abs_time); }
+
+ //!The same as: while (!pred()) {
+ //! if (!timed_wait(lock, abs_time)) return pred();
+ //! } return true;
+ template <typename L, typename Pr>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+ { return m_cond.timed_wait(lock, abs_time, pred); }
+
+ //!Erases a named condition from the system.
+ //!Returns false on error. Never throws.
+ static bool remove(const char *name)
+ { return shared_memory_object::remove(name); }
+
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ private:
+
+ class internal_condition_members
+ {
+ public:
+ typedef interprocess_mutex mutex_type;
+ typedef interprocess_condition condvar_type;
+
+ condvar_type& get_condvar() { return m_cond; }
+ mutex_type& get_mutex() { return m_mtx; }
+
+ private:
+ mutex_type m_mtx;
+ condvar_type m_cond;
+ };
+
+ typedef ipcdetail::condition_any_wrapper<internal_condition_members> internal_condition;
+
+ internal_condition m_cond;
+
+ friend class boost::interprocess::ipcdetail::interprocess_tester;
+ void dont_close_on_destruction()
+ { interprocess_tester::dont_close_on_destruction(m_shmem); }
+
+ typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> open_create_impl_t;
+ open_create_impl_t m_shmem;
+
+ template <class T, class Arg> friend class boost::interprocess::ipcdetail::named_creation_functor;
+ typedef boost::interprocess::ipcdetail::named_creation_functor<internal_condition> construct_func_t;
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+};
+
+} //namespace ipcdetail
+} //namespace interprocess
+} //namespace boost
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif // BOOST_INTERPROCESS_SHM_NAMED_CONDITION_ANY_HPP
diff --git a/boost/interprocess/sync/shm/named_creation_functor.hpp b/boost/interprocess/sync/shm/named_creation_functor.hpp
index 9d752c8..234e072 100644
--- a/boost/interprocess/sync/shm/named_creation_functor.hpp
+++ b/boost/interprocess/sync/shm/named_creation_functor.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2007-2012. 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)
//
@@ -11,6 +11,10 @@
#ifndef BOOST_INTERPROCESS_SYNC_NAMED_CREATION_FUNCTOR_HPP
#define BOOST_INTERPROCESS_SYNC_NAMED_CREATION_FUNCTOR_HPP
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/detail/mpl.hpp>
@@ -38,7 +42,7 @@ class named_creation_functor
{ new(address)T(m_arg); }
bool operator()(void *address, std::size_t, bool created) const
- {
+ {
switch(m_creation_type){
case DoOpen:
return true;
@@ -56,6 +60,10 @@ class named_creation_functor
break;
}
}
+
+ std::size_t get_min_size() const
+ { return sizeof(T); }
+
private:
create_enum_t m_creation_type;
Arg m_arg;
diff --git a/boost/interprocess/sync/shm/named_mutex.hpp b/boost/interprocess/sync/shm/named_mutex.hpp
index f32fa70..fc66f3a 100644
--- a/boost/interprocess/sync/shm/named_mutex.hpp
+++ b/boost/interprocess/sync/shm/named_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_SHM_NAMED_MUTEX_HPP
#define BOOST_INTERPROCESS_SHM_NAMED_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -42,14 +42,14 @@ class named_condition;
//!each process should have it's own named mutex.
class shm_named_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
shm_named_mutex();
shm_named_mutex(const shm_named_mutex &);
shm_named_mutex &operator=(const shm_named_mutex &);
friend class named_condition;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Creates a global interprocess_mutex with a name.
@@ -99,20 +99,21 @@ class shm_named_mutex
//!Returns false on error. Never throws.
static bool remove(const char *name);
- /// @cond
- interprocess_mutex *mutex() const
- { return static_cast<interprocess_mutex*>(m_shmem.get_user_address()); }
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ typedef interprocess_mutex internal_mutex_type;
+ interprocess_mutex &internal_mutex()
+ { return *static_cast<interprocess_mutex*>(m_shmem.get_user_address()); }
private:
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
-
- ipcdetail::managed_open_or_create_impl<shared_memory_object> m_shmem;
+ typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> open_create_impl_t;
+ open_create_impl_t m_shmem;
typedef ipcdetail::named_creation_functor<interprocess_mutex> construct_func_t;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline void shm_named_mutex::dont_close_on_destruction()
{ ipcdetail::interprocess_tester::dont_close_on_destruction(m_shmem); }
@@ -124,8 +125,7 @@ inline shm_named_mutex::shm_named_mutex(create_only_t, const char *name, const p
: m_shmem (create_only
,name
,sizeof(interprocess_mutex) +
- ipcdetail::managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(ipcdetail::DoCreate)
@@ -136,8 +136,7 @@ inline shm_named_mutex::shm_named_mutex(open_or_create_t, const char *name, cons
: m_shmem (open_or_create
,name
,sizeof(interprocess_mutex) +
- ipcdetail::managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(ipcdetail::DoOpenOrCreate)
@@ -153,27 +152,21 @@ inline shm_named_mutex::shm_named_mutex(open_only_t, const char *name)
{}
inline void shm_named_mutex::lock()
-{ this->mutex()->lock(); }
+{ this->internal_mutex().lock(); }
inline void shm_named_mutex::unlock()
-{ this->mutex()->unlock(); }
+{ this->internal_mutex().unlock(); }
inline bool shm_named_mutex::try_lock()
-{ return this->mutex()->try_lock(); }
+{ return this->internal_mutex().try_lock(); }
inline bool shm_named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- return this->mutex()->timed_lock(abs_time);
-}
+{ return this->internal_mutex().timed_lock(abs_time); }
inline bool shm_named_mutex::remove(const char *name)
{ return shared_memory_object::remove(name); }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace ipcdetail {
} //namespace interprocess {
diff --git a/boost/interprocess/sync/shm/named_recursive_mutex.hpp b/boost/interprocess/sync/shm/named_recursive_mutex.hpp
index 7235571..988ef66 100644
--- a/boost/interprocess/sync/shm/named_recursive_mutex.hpp
+++ b/boost/interprocess/sync/shm/named_recursive_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_SHM_NAMED_RECURSIVE_MUTEX_HPP
#define BOOST_INTERPROCESS_SHM_NAMED_RECURSIVE_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -33,18 +33,18 @@ namespace boost {
namespace interprocess {
namespace ipcdetail {
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
class interprocess_tester;
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
class shm_named_recursive_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
shm_named_recursive_mutex();
shm_named_recursive_mutex(const shm_named_recursive_mutex &);
shm_named_recursive_mutex &operator=(const shm_named_recursive_mutex &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Creates a global recursive_mutex with a name.
@@ -94,17 +94,17 @@ class shm_named_recursive_mutex
//!from the system
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class interprocess_tester;
void dont_close_on_destruction();
interprocess_recursive_mutex *mutex() const
{ return static_cast<interprocess_recursive_mutex*>(m_shmem.get_user_address()); }
-
- managed_open_or_create_impl<shared_memory_object> m_shmem;
+ typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> open_create_impl_t;
+ open_create_impl_t m_shmem;
typedef named_creation_functor<interprocess_recursive_mutex> construct_func_t;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
inline shm_named_recursive_mutex::~shm_named_recursive_mutex()
@@ -117,8 +117,7 @@ inline shm_named_recursive_mutex::shm_named_recursive_mutex(create_only_t, const
: m_shmem (create_only
,name
,sizeof(interprocess_recursive_mutex) +
- managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(DoCreate)
@@ -129,8 +128,7 @@ inline shm_named_recursive_mutex::shm_named_recursive_mutex(open_or_create_t, co
: m_shmem (open_or_create
,name
,sizeof(interprocess_recursive_mutex) +
- managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(DoOpenOrCreate)
@@ -155,13 +153,7 @@ inline bool shm_named_recursive_mutex::try_lock()
{ return this->mutex()->try_lock(); }
inline bool shm_named_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- return this->mutex()->timed_lock(abs_time);
-}
+{ return this->mutex()->timed_lock(abs_time); }
inline bool shm_named_recursive_mutex::remove(const char *name)
{ return shared_memory_object::remove(name); }
diff --git a/boost/interprocess/sync/shm/named_semaphore.hpp b/boost/interprocess/sync/shm/named_semaphore.hpp
index c6d3830..d952d12 100644
--- a/boost/interprocess/sync/shm/named_semaphore.hpp
+++ b/boost/interprocess/sync/shm/named_semaphore.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_SHM_NAMED_SEMAPHORE_HPP
#define BOOST_INTERPROCESS_SHM_NAMED_SEMAPHORE_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -33,13 +33,13 @@ namespace ipcdetail {
class shm_named_semaphore
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
shm_named_semaphore();
shm_named_semaphore(const shm_named_semaphore &);
shm_named_semaphore &operator=(const shm_named_semaphore &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
shm_named_semaphore(create_only_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
@@ -57,7 +57,7 @@ class shm_named_semaphore
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class interprocess_tester;
void dont_close_on_destruction();
@@ -65,9 +65,10 @@ class shm_named_semaphore
interprocess_semaphore *semaphore() const
{ return static_cast<interprocess_semaphore*>(m_shmem.get_user_address()); }
- managed_open_or_create_impl<shared_memory_object> m_shmem;
+ typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> open_create_impl_t;
+ open_create_impl_t m_shmem;
typedef named_creation_functor<interprocess_semaphore, int> construct_func_t;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
inline shm_named_semaphore::~shm_named_semaphore()
@@ -81,8 +82,7 @@ inline shm_named_semaphore::shm_named_semaphore
: m_shmem (create_only
,name
,sizeof(interprocess_semaphore) +
- managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(DoCreate, initialCount)
@@ -94,8 +94,7 @@ inline shm_named_semaphore::shm_named_semaphore
: m_shmem (open_or_create
,name
,sizeof(interprocess_semaphore) +
- managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(DoOpenOrCreate, initialCount)
@@ -121,13 +120,7 @@ inline bool shm_named_semaphore::try_wait()
{ return semaphore()->try_wait(); }
inline bool shm_named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait();
- return true;
- }
- return semaphore()->timed_wait(abs_time);
-}
+{ return semaphore()->timed_wait(abs_time); }
inline bool shm_named_semaphore::remove(const char *name)
{ return shared_memory_object::remove(name); }
diff --git a/boost/interprocess/sync/shm/named_upgradable_mutex.hpp b/boost/interprocess/sync/shm/named_upgradable_mutex.hpp
index 0975a6e..4c39792 100644
--- a/boost/interprocess/sync/shm/named_upgradable_mutex.hpp
+++ b/boost/interprocess/sync/shm/named_upgradable_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_NAMED_UPGRADABLE_MUTEX_HPP
#define BOOST_INTERPROCESS_NAMED_UPGRADABLE_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -32,9 +32,9 @@
namespace boost {
namespace interprocess {
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
namespace ipcdetail{ class interprocess_tester; }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
class named_condition;
@@ -43,13 +43,13 @@ class named_condition;
//!each process should have it's own named upgradable mutex.
class named_upgradable_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
named_upgradable_mutex();
named_upgradable_mutex(const named_upgradable_mutex &);
named_upgradable_mutex &operator=(const named_upgradable_mutex &);
friend class named_condition;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Creates a global upgradable mutex with a name.
@@ -221,7 +221,7 @@ class named_upgradable_mutex
//!Returns false on error. Never throws.
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
@@ -229,12 +229,13 @@ class named_upgradable_mutex
interprocess_upgradable_mutex *mutex() const
{ return static_cast<interprocess_upgradable_mutex*>(m_shmem.get_user_address()); }
- ipcdetail::managed_open_or_create_impl<shared_memory_object> m_shmem;
+ typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> open_create_impl_t;
+ open_create_impl_t m_shmem;
typedef ipcdetail::named_creation_functor<interprocess_upgradable_mutex> construct_func_t;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline named_upgradable_mutex::~named_upgradable_mutex()
{}
@@ -244,8 +245,7 @@ inline named_upgradable_mutex::named_upgradable_mutex
: m_shmem (create_only
,name
,sizeof(interprocess_upgradable_mutex) +
- ipcdetail::managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(ipcdetail::DoCreate)
@@ -257,8 +257,7 @@ inline named_upgradable_mutex::named_upgradable_mutex
: m_shmem (open_or_create
,name
,sizeof(interprocess_upgradable_mutex) +
- ipcdetail::managed_open_or_create_impl<shared_memory_object>::
- ManagedOpenOrCreateUserOffset
+ open_create_impl_t::ManagedOpenOrCreateUserOffset
,read_write
,0
,construct_func_t(ipcdetail::DoOpenOrCreate)
@@ -288,13 +287,7 @@ inline bool named_upgradable_mutex::try_lock()
inline bool named_upgradable_mutex::timed_lock
(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- return this->mutex()->timed_lock(abs_time);
-}
+{ return this->mutex()->timed_lock(abs_time); }
inline void named_upgradable_mutex::lock_upgradable()
{ this->mutex()->lock_upgradable(); }
@@ -307,13 +300,7 @@ inline bool named_upgradable_mutex::try_lock_upgradable()
inline bool named_upgradable_mutex::timed_lock_upgradable
(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock_upgradable();
- return true;
- }
- return this->mutex()->timed_lock_upgradable(abs_time);
-}
+{ return this->mutex()->timed_lock_upgradable(abs_time); }
inline void named_upgradable_mutex::lock_sharable()
{ this->mutex()->lock_sharable(); }
@@ -326,13 +313,7 @@ inline bool named_upgradable_mutex::try_lock_sharable()
inline bool named_upgradable_mutex::timed_lock_sharable
(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock_sharable();
- return true;
- }
- return this->mutex()->timed_lock_sharable(abs_time);
-}
+{ return this->mutex()->timed_lock_sharable(abs_time); }
inline void named_upgradable_mutex::unlock_and_lock_upgradable()
{ this->mutex()->unlock_and_lock_upgradable(); }
@@ -362,7 +343,7 @@ inline bool named_upgradable_mutex::try_unlock_sharable_and_lock_upgradable()
inline bool named_upgradable_mutex::remove(const char *name)
{ return shared_memory_object::remove(name); }
-/// @endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace interprocess {
} //namespace boost {
diff --git a/boost/interprocess/sync/spin/condition.hpp b/boost/interprocess/sync/spin/condition.hpp
index 55dd79b..e587c32 100644
--- a/boost/interprocess/sync/spin/condition.hpp
+++ b/boost/interprocess/sync/spin/condition.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,6 +11,10 @@
#ifndef BOOST_INTERPROCESS_DETAIL_SPIN_CONDITION_HPP
#define BOOST_INTERPROCESS_DETAIL_SPIN_CONDITION_HPP
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/sync/spin/mutex.hpp>
@@ -19,7 +23,8 @@
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
-#include <boost/move/move.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
+#include <boost/move/utility_core.hpp>
#include <boost/cstdint.hpp>
namespace boost {
@@ -40,24 +45,26 @@ class spin_condition
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
{
+ if (!lock)
+ throw lock_exception();
+ //Handle infinity absolute time here to avoid complications in do_timed_wait
if(abs_time == boost::posix_time::pos_infin){
this->wait(lock);
return true;
}
- if (!lock)
- throw lock_exception();
return this->do_timed_wait(abs_time, *lock.mutex());
}
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
{
+ if (!lock)
+ throw lock_exception();
+ //Handle infinity absolute time here to avoid complications in do_timed_wait
if(abs_time == boost::posix_time::pos_infin){
this->wait(lock, pred);
return true;
}
- if (!lock)
- throw lock_exception();
while (!pred()){
if (!this->do_timed_wait(abs_time, *lock.mutex()))
return pred();
@@ -110,8 +117,10 @@ inline spin_condition::spin_condition()
}
inline spin_condition::~spin_condition()
-{
- //Trivial destructor
+{
+ //Notify all waiting threads
+ //to allow POSIX semantics on condition destruction
+ this->notify_all();
}
inline void spin_condition::notify_one()
@@ -140,15 +149,10 @@ inline void spin_condition::notify(boost::uint32_t command)
}
//Notify that all threads should execute wait logic
+ spin_wait swait;
while(SLEEP != atomic_cas32(const_cast<boost::uint32_t*>(&m_command), command, SLEEP)){
- thread_yield();
+ swait.yield();
}
-/*
- //Wait until the threads are woken
- while(SLEEP != atomic_cas32(const_cast<boost::uint32_t*>(&m_command), 0)){
- thread_yield();
- }
-*/
//The enter mutex will rest locked until the last waiting thread unlocks it
}
@@ -171,7 +175,7 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
InterprocessMutex &mut)
{
boost::posix_time::ptime now = microsec_clock::universal_time();
-
+
if(tout_enabled){
if(now >= abs_time) return false;
}
@@ -205,14 +209,15 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
//By default, we suppose that no timeout has happened
bool timed_out = false, unlock_enter_mut= false;
-
+
//Loop until a notification indicates that the thread should
//exit or timeout occurs
while(1){
//The thread sleeps/spins until a spin_condition commands a notification
//Notification occurred, we will lock the checking mutex so that
+ spin_wait swait;
while(atomic_read32(&m_command) == SLEEP){
- thread_yield();
+ swait.yield();
//Check for timeout
if(tout_enabled){
@@ -253,7 +258,7 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
continue;
}
else if(result == NOTIFY_ONE){
- //If it was a NOTIFY_ONE command, only this thread should
+ //If it was a NOTIFY_ONE command, only this thread should
//exit. This thread has atomically marked command as sleep before
//so no other thread will exit.
//Decrement wait count.
diff --git a/boost/interprocess/sync/spin/interprocess_barrier.hpp b/boost/interprocess/sync/spin/interprocess_barrier.hpp
index f8ee099..5f88dd4 100644
--- a/boost/interprocess/sync/spin/interprocess_barrier.hpp
+++ b/boost/interprocess/sync/spin/interprocess_barrier.hpp
@@ -12,6 +12,10 @@
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
namespace boost {
namespace interprocess {
diff --git a/boost/interprocess/sync/spin/mutex.hpp b/boost/interprocess/sync/spin/mutex.hpp
index 926f723..154dc6d 100644
--- a/boost/interprocess/sync/spin/mutex.hpp
+++ b/boost/interprocess/sync/spin/mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_DETAIL_SPIN_MUTEX_HPP
#define BOOST_INTERPROCESS_DETAIL_SPIN_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -22,6 +22,7 @@
#include <boost/interprocess/detail/atomic.hpp>
#include <boost/cstdint.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
+#include <boost/interprocess/sync/detail/common_algorithms.hpp>
namespace boost {
namespace interprocess {
@@ -59,48 +60,16 @@ inline spin_mutex::~spin_mutex()
}
inline void spin_mutex::lock(void)
-{
- do{
- boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
-
- if (m_s == 1 && prev_s == 0){
- break;
- }
- // relinquish current timeslice
- ipcdetail::thread_yield();
- }while (true);
-}
+{ return ipcdetail::try_based_lock(*this); }
inline bool spin_mutex::try_lock(void)
{
- boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
+ boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
return m_s == 1 && prev_s == 0;
}
inline bool spin_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- //Obtain current count and target time
- boost::posix_time::ptime now = microsec_clock::universal_time();
-
- do{
- if(this->try_lock()){
- break;
- }
- now = microsec_clock::universal_time();
-
- if(now >= abs_time){
- return false;
- }
- // relinquish current time slice
- ipcdetail::thread_yield();
- }while (true);
-
- return true;
-}
+{ return ipcdetail::try_based_timed_lock(*this, abs_time); }
inline void spin_mutex::unlock(void)
{ ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 0, 1); }
diff --git a/boost/interprocess/sync/spin/recursive_mutex.hpp b/boost/interprocess/sync/spin/recursive_mutex.hpp
index a763f9c..ce6b0d1 100644
--- a/boost/interprocess/sync/spin/recursive_mutex.hpp
+++ b/boost/interprocess/sync/spin/recursive_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -27,7 +27,7 @@
#ifndef BOOST_INTERPROCESS_DETAIL_SPIN_RECURSIVE_MUTEX_HPP
#define BOOST_INTERPROCESS_DETAIL_SPIN_RECURSIVE_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -118,10 +118,6 @@ inline bool spin_recursive_mutex::try_lock()
inline bool spin_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
handle_t old_id;
ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
@@ -133,6 +129,7 @@ inline bool spin_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs
++m_nLockCount;
return true;
}
+ //m_mutex supports abs_time so no need to check it
if(m_mutex.timed_lock(abs_time)){
ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
m_nLockCount = 1;
diff --git a/boost/interprocess/sync/spin/semaphore.hpp b/boost/interprocess/sync/spin/semaphore.hpp
index 1b8cac3..94922af 100644
--- a/boost/interprocess/sync/spin/semaphore.hpp
+++ b/boost/interprocess/sync/spin/semaphore.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_DETAIL_SPIN_SEMAPHORE_HPP
#define BOOST_INTERPROCESS_DETAIL_SPIN_SEMAPHORE_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -20,6 +20,8 @@
#include <boost/interprocess/detail/atomic.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/detail/common_algorithms.hpp>
+#include <boost/interprocess/sync/detail/locks.hpp>
#include <boost/cstdint.hpp>
namespace boost {
@@ -59,11 +61,8 @@ inline void spin_semaphore::post()
inline void spin_semaphore::wait()
{
- while(!ipcdetail::atomic_add_unless32(&m_count, boost::uint32_t(-1), boost::uint32_t(0))){
- while(ipcdetail::atomic_read32(&m_count) == 0){
- ipcdetail::thread_yield();
- }
- }
+ ipcdetail::lock_to_wait<spin_semaphore> lw(*this);
+ return ipcdetail::try_based_lock(lw);
}
inline bool spin_semaphore::try_wait()
@@ -73,29 +72,10 @@ inline bool spin_semaphore::try_wait()
inline bool spin_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait();
- return true;
- }
- //Obtain current count and target time
- boost::posix_time::ptime now(microsec_clock::universal_time());
-
- do{
- if(this->try_wait()){
- break;
- }
- now = microsec_clock::universal_time();
-
- if(now >= abs_time){
- return this->try_wait();
- }
- // relinquish current time slice
- ipcdetail::thread_yield();
- }while (true);
- return true;
+ ipcdetail::lock_to_wait<spin_semaphore> lw(*this);
+ return ipcdetail::try_based_timed_lock(lw, abs_time);
}
-
//inline int spin_semaphore::get_count() const
//{
//return (int)ipcdetail::atomic_read32(&m_count);
diff --git a/boost/interprocess/sync/spin/wait.hpp b/boost/interprocess/sync/spin/wait.hpp
new file mode 100644
index 0000000..220699b
--- /dev/null
+++ b/boost/interprocess/sync/spin/wait.hpp
@@ -0,0 +1,181 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Peter Dimov 2008.
+// (C) Copyright Ion Gaztanaga 2013-2013. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//Parts of this file come from boost/smart_ptr/detail/yield_k.hpp
+//Many thanks to Peter Dimov.
+
+#ifndef BOOST_INTERPROCESS_SYNC_WAIT_HPP_INCLUDED
+#define BOOST_INTERPROCESS_SYNC_WAIT_HPP_INCLUDED
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+
+//#define BOOST_INTERPROCESS_SPIN_WAIT_DEBUG
+#ifdef BOOST_INTERPROCESS_SPIN_WAIT_DEBUG
+#include <iostream>
+#endif
+
+// BOOST_INTERPROCESS_SMT_PAUSE
+
+#if defined(_MSC_VER) && ( defined(_M_IX86) || defined(_M_X64) )
+
+extern "C" void _mm_pause();
+#pragma intrinsic( _mm_pause )
+
+#define BOOST_INTERPROCESS_SMT_PAUSE _mm_pause();
+
+#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) && !defined(_CRAYC)
+
+#define BOOST_INTERPROCESS_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
+
+#endif
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail {
+
+template<int Dummy = 0>
+class num_core_holder
+{
+ public:
+ static unsigned int get()
+ {
+ if(!num_cores){
+ return ipcdetail::get_num_cores();
+ }
+ else{
+ return num_cores;
+ }
+ }
+
+ private:
+ static unsigned int num_cores;
+};
+
+template<int Dummy>
+unsigned int num_core_holder<Dummy>::num_cores = ipcdetail::get_num_cores();
+
+} //namespace ipcdetail {
+
+class spin_wait
+{
+ public:
+
+ static const unsigned int nop_pause_limit = 32u;
+ spin_wait()
+ : m_count_start(), m_ul_yield_only_counts(), m_k()
+ {}
+
+ #ifdef BOOST_INTERPROCESS_SPIN_WAIT_DEBUG
+ ~spin_wait()
+ {
+ if(m_k){
+ std::cout << "final m_k: " << m_k
+ << " system tick(us): " << ipcdetail::get_system_tick_us() << std::endl;
+ }
+ }
+ #endif
+
+ unsigned int count() const
+ { return m_k; }
+
+ void yield()
+ {
+ //Lazy initialization of limits
+ if( !m_k){
+ this->init_limits();
+ }
+ //Nop tries
+ if( m_k < (nop_pause_limit >> 2) ){
+
+ }
+ //Pause tries if the processor supports it
+ #if defined(BOOST_INTERPROCESS_SMT_PAUSE)
+ else if( m_k < nop_pause_limit ){
+ BOOST_INTERPROCESS_SMT_PAUSE
+ }
+ #endif
+ //Yield/Sleep strategy
+ else{
+ //Lazy initialization of tick information
+ if(m_k == nop_pause_limit){
+ this->init_tick_info();
+ }
+ else if( this->yield_or_sleep() ){
+ ipcdetail::thread_yield();
+ }
+ else{
+ ipcdetail::thread_sleep_tick();
+ }
+ }
+ ++m_k;
+ }
+
+ void reset()
+ {
+ m_k = 0u;
+ }
+
+ private:
+
+ void init_limits()
+ {
+ unsigned int num_cores = ipcdetail::num_core_holder<0>::get();
+ m_k = num_cores > 1u ? 0u : nop_pause_limit;
+ }
+
+ void init_tick_info()
+ {
+ m_ul_yield_only_counts = ipcdetail::get_system_tick_in_highres_counts();
+ m_count_start = ipcdetail::get_current_system_highres_count();
+ }
+
+ //Returns true if yield must be called, false is sleep must be called
+ bool yield_or_sleep()
+ {
+ if(!m_ul_yield_only_counts){ //If yield-only limit was reached then yield one in every two tries
+ return (m_k & 1u) != 0;
+ }
+ else{ //Try to see if we've reched yield-only time limit
+ const ipcdetail::OS_highres_count_t now = ipcdetail::get_current_system_highres_count();
+ const ipcdetail::OS_highres_count_t elapsed = ipcdetail::system_highres_count_subtract(now, m_count_start);
+ if(!ipcdetail::system_highres_count_less_ul(elapsed, m_ul_yield_only_counts)){
+ #ifdef BOOST_INTERPROCESS_SPIN_WAIT_DEBUG
+ std::cout << "elapsed!\n"
+ << " m_ul_yield_only_counts: " << m_ul_yield_only_counts
+ << " system tick(us): " << ipcdetail::get_system_tick_us() << '\n'
+ << " m_k: " << m_k << " elapsed counts: ";
+ ipcdetail::ostream_highres_count(std::cout, elapsed) << std::endl;
+ #endif
+ //Yield-only time reached, now it's time to sleep
+ m_ul_yield_only_counts = 0ul;
+ return false;
+ }
+ }
+ return true; //Otherwise yield
+ }
+
+ ipcdetail::OS_highres_count_t m_count_start;
+ unsigned long m_ul_yield_only_counts;
+ unsigned int m_k;
+};
+
+} // namespace interprocess
+} // namespace boost
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_INTERPROCESS_SYNC_WAIT_HPP_INCLUDED
diff --git a/boost/interprocess/sync/upgradable_lock.hpp b/boost/interprocess/sync/upgradable_lock.hpp
index fb86374..646019b 100644
--- a/boost/interprocess/sync/upgradable_lock.hpp
+++ b/boost/interprocess/sync/upgradable_lock.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -16,7 +16,7 @@
#ifndef BOOST_INTERPROCESS_UPGRADABLE_LOCK_HPP
#define BOOST_INTERPROCESS_UPGRADABLE_LOCK_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -28,7 +28,7 @@
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/exceptions.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility_core.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
//!\file
@@ -52,13 +52,13 @@ class upgradable_lock
{
public:
typedef UpgradableMutex mutex_type;
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
typedef upgradable_lock<UpgradableMutex> this_type;
explicit upgradable_lock(scoped_lock<mutex_type>&);
typedef bool this_type::*unspecified_bool_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(upgradable_lock)
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
//!Effects: Default constructs a upgradable_lock.
@@ -207,7 +207,7 @@ class upgradable_lock
//!Notes: The sharable_lock changes from a state of not owning the mutex,
//! to owning the mutex, blocking if necessary.
void lock()
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
mp_mutex->lock_upgradable();
@@ -223,7 +223,7 @@ class upgradable_lock
//! mutex_type does not support try_lock_upgradable(), this function will
//! fail at compile time if instantiated, but otherwise have no effect.
bool try_lock()
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
m_locked = mp_mutex->try_lock_upgradable();
@@ -240,7 +240,7 @@ class upgradable_lock
//! timed_lock_upgradable(abs_time), this function will fail at compile
//! time if instantiated, but otherwise have no effect.
bool timed_lock(const boost::posix_time::ptime& abs_time)
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
m_locked = mp_mutex->timed_lock_upgradable(abs_time);
@@ -294,11 +294,11 @@ class upgradable_lock
std::swap(m_locked, other.m_locked);
}
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
mutex_type *mp_mutex;
bool m_locked;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
} // namespace interprocess
diff --git a/boost/interprocess/sync/windows/condition.hpp b/boost/interprocess/sync/windows/condition.hpp
index 9695c21..d5b77c7 100644
--- a/boost/interprocess/sync/windows/condition.hpp
+++ b/boost/interprocess/sync/windows/condition.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,6 +11,10 @@
#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_CONDITION_HPP
#define BOOST_INTERPROCESS_DETAIL_WINDOWS_CONDITION_HPP
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
@@ -33,63 +37,38 @@ class windows_condition
windows_condition &operator=(const windows_condition &);
public:
- windows_condition();
- ~windows_condition();
+ windows_condition()
+ : m_condition_data()
+ {}
+
+ ~windows_condition()
+ {
+ //Notify all waiting threads
+ //to allow POSIX semantics on condition destruction
+ this->notify_all();
+ }
+
+ void notify_one()
+ { m_condition_data.notify_one(); }
- void notify_one();
- void notify_all();
+ void notify_all()
+ { m_condition_data.notify_all(); }
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
- {
- if(abs_time == boost::posix_time::pos_infin){
- this->wait(lock);
- return true;
- }
- if (!lock)
- throw lock_exception();
- return this->do_timed_wait(abs_time, *lock.mutex());
- }
+ { return m_condition_data.timed_wait(lock, abs_time); }
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
- {
- if(abs_time == boost::posix_time::pos_infin){
- this->wait(lock, pred);
- return true;
- }
- if (!lock)
- throw lock_exception();
- while (!pred()){
- if (!this->do_timed_wait(abs_time, *lock.mutex()))
- return pred();
- }
- return true;
- }
+ { return m_condition_data.timed_wait(lock, abs_time, pred); }
template <typename L>
void wait(L& lock)
- {
- if (!lock)
- throw lock_exception();
- do_wait(*lock.mutex());
- }
+ { m_condition_data.wait(lock); }
template <typename L, typename Pr>
void wait(L& lock, Pr pred)
- {
- if (!lock)
- throw lock_exception();
-
- while (!pred())
- do_wait(*lock.mutex());
- }
-
- template<class InterprocessMutex>
- void do_wait(InterprocessMutex &mut);
-
- template<class InterprocessMutex>
- bool do_timed_wait(const boost::posix_time::ptime &abs_time, InterprocessMutex &mut);
+ { m_condition_data.wait(lock, pred); }
private:
@@ -132,33 +111,11 @@ class windows_condition
windows_semaphore m_sem_block_queue;
windows_semaphore m_sem_block_lock;
windows_mutex m_mtx_unblock_lock;
- } m_condition_data;
+ };
- typedef condition_algorithm_8a<condition_data> algorithm_type;
+ ipcdetail::condition_8a_wrapper<condition_data> m_condition_data;
};
-inline windows_condition::windows_condition()
- : m_condition_data()
-{}
-
-inline windows_condition::~windows_condition()
-{}
-
-inline void windows_condition::notify_one()
-{ algorithm_type::signal(m_condition_data, false); }
-
-inline void windows_condition::notify_all()
-{ algorithm_type::signal(m_condition_data, true); }
-
-template<class InterprocessMutex>
-inline void windows_condition::do_wait(InterprocessMutex &mut)
-{ algorithm_type::wait(m_condition_data, false, boost::posix_time::ptime(), mut); }
-
-template<class InterprocessMutex>
-inline bool windows_condition::do_timed_wait
- (const boost::posix_time::ptime &abs_time, InterprocessMutex &mut)
-{ return algorithm_type::wait(m_condition_data, true, abs_time, mut); }
-
} //namespace ipcdetail
} //namespace interprocess
} //namespace boost
diff --git a/boost/interprocess/sync/windows/mutex.hpp b/boost/interprocess/sync/windows/mutex.hpp
index 477acd3..0b1958c 100644
--- a/boost/interprocess/sync/windows/mutex.hpp
+++ b/boost/interprocess/sync/windows/mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_MUTEX_HPP
#define BOOST_INTERPROCESS_DETAIL_WINDOWS_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -57,8 +57,8 @@ inline windows_mutex::windows_mutex()
bool open_or_created;
(void)handles.obtain_mutex(this->id_, &open_or_created);
//The mutex must be created, never opened
- assert(open_or_created);
- assert(open_or_created && winapi::get_last_error() != winapi::error_already_exists);
+ BOOST_ASSERT(open_or_created);
+ BOOST_ASSERT(open_or_created && winapi::get_last_error() != winapi::error_already_exists);
(void)open_or_created;
}
diff --git a/boost/interprocess/sync/windows/named_condition.hpp b/boost/interprocess/sync/windows/named_condition.hpp
index 403e826..ba220fd 100644
--- a/boost/interprocess/sync/windows/named_condition.hpp
+++ b/boost/interprocess/sync/windows/named_condition.hpp
@@ -11,319 +11,19 @@
#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_HPP
#define BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/creation_tags.hpp>
-#include <boost/interprocess/permissions.hpp>
-#include <boost/interprocess/detail/interprocess_tester.hpp>
-#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-#include <boost/interprocess/sync/windows/named_sync.hpp>
-#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
-#include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
+#include <boost/interprocess/sync/windows/named_condition_any.hpp>
namespace boost {
namespace interprocess {
namespace ipcdetail {
-class windows_named_condition
-{
- /// @cond
-
- //Non-copyable
- windows_named_condition();
- windows_named_condition(const windows_named_condition &);
- windows_named_condition &operator=(const windows_named_condition &);
- /// @endcond
-
- public:
- windows_named_condition(create_only_t, const char *name, const permissions &perm = permissions());
-
- windows_named_condition(open_or_create_t, const char *name, const permissions &perm = permissions());
-
- windows_named_condition(open_only_t, const char *name);
-
- ~windows_named_condition();
-
- //!If there is a thread waiting on *this, change that
- //!thread's state to ready. Otherwise there is no effect.*/
- void notify_one();
-
- //!Change the state of all threads waiting on *this to ready.
- //!If there are no waiting threads, notify_all() has no effect.
- void notify_all();
-
- //!Releases the lock on the named_mutex object associated with lock, blocks
- //!the current thread of execution until readied by a call to
- //!this->notify_one() or this->notify_all(), and then reacquires the lock.
- template <typename L>
- void wait(L& lock);
-
- //!The same as:
- //!while (!pred()) wait(lock)
- template <typename L, typename Pr>
- void wait(L& lock, Pr pred);
-
- //!Releases the lock on the named_mutex object associated with lock, blocks
- //!the current thread of execution until readied by a call to
- //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
- //!and then reacquires the lock.
- //!Returns: false if time abs_time is reached, otherwise true.
- template <typename L>
- bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time);
-
- //!The same as: while (!pred()) {
- //! if (!timed_wait(lock, abs_time)) return pred();
- //! } return true;
- template <typename L, typename Pr>
- bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred);
-
- static bool remove(const char *name);
-
- /// @cond
- private:
- friend class interprocess_tester;
- void dont_close_on_destruction();
-
- template <class InterprocessMutex>
- void do_wait(InterprocessMutex& lock);
-
- template <class InterprocessMutex>
- bool do_timed_wait(const boost::posix_time::ptime &abs_time, InterprocessMutex& lock);
-
- struct condition_data
- {
- typedef boost::int32_t integer_type;
- typedef winapi_semaphore_wrapper semaphore_type;
- typedef winapi_mutex_wrapper mutex_type;
-
- integer_type &get_nwaiters_blocked()
- { return m_nwaiters_blocked; }
-
- integer_type &get_nwaiters_gone()
- { return m_nwaiters_gone; }
-
- integer_type &get_nwaiters_to_unblock()
- { return m_nwaiters_to_unblock; }
-
- semaphore_type &get_sem_block_queue()
- { return m_sem_block_queue; }
-
- semaphore_type &get_sem_block_lock()
- { return m_sem_block_lock; }
-
- mutex_type &get_mtx_unblock_lock()
- { return m_mtx_unblock_lock; }
-
- integer_type m_nwaiters_blocked;
- integer_type m_nwaiters_gone;
- integer_type m_nwaiters_to_unblock;
- winapi_semaphore_wrapper m_sem_block_queue;
- winapi_semaphore_wrapper m_sem_block_lock;
- winapi_mutex_wrapper m_mtx_unblock_lock;
- } m_condition_data;
-
- typedef condition_algorithm_8a<condition_data> algorithm_type;
-
- class named_cond_callbacks : public windows_named_sync_interface
- {
- typedef __int64 sem_count_t;
- mutable sem_count_t sem_counts [2];
-
- public:
- named_cond_callbacks(condition_data &cond_data)
- : m_condition_data(cond_data)
- {}
-
- virtual std::size_t get_data_size() const
- { return sizeof(sem_counts); }
-
- virtual const void *buffer_with_final_data_to_file()
- {
- sem_counts[0] = m_condition_data.m_sem_block_queue.value();
- sem_counts[1] = m_condition_data.m_sem_block_lock.value();
- return &sem_counts;
- }
-
- virtual const void *buffer_with_init_data_to_file()
- {
- sem_counts[0] = 0;
- sem_counts[1] = 1;
- return &sem_counts;
- }
-
- virtual void *buffer_to_store_init_data_from_file()
- { return &sem_counts; }
-
- virtual bool open(create_enum_t, const char *id_name)
- {
- m_condition_data.m_nwaiters_blocked = 0;
- m_condition_data.m_nwaiters_gone = 0;
- m_condition_data.m_nwaiters_to_unblock = 0;
-
- //Now open semaphores and mutex.
- //Use local variables + swap to guarantee consistent
- //initialization and cleanup in case any opening fails
- permissions perm;
- perm.set_unrestricted();
- std::string aux_str = "Global\\bipc.cond.";
- aux_str += id_name;
- std::size_t pos = aux_str.size();
-
- //sem_block_queue
- aux_str += "_bq";
- winapi_semaphore_wrapper sem_block_queue;
- bool created;
- if(!sem_block_queue.open_or_create
- (aux_str.c_str(), sem_counts[0], winapi_semaphore_wrapper::MaxCount, perm, created))
- return false;
- aux_str.erase(pos);
-
- //sem_block_lock
- aux_str += "_bl";
- winapi_semaphore_wrapper sem_block_lock;
- if(!sem_block_lock.open_or_create
- (aux_str.c_str(), sem_counts[1], winapi_semaphore_wrapper::MaxCount, perm, created))
- return false;
- aux_str.erase(pos);
-
- //mtx_unblock_lock
- aux_str += "_ul";
- winapi_mutex_wrapper mtx_unblock_lock;
- if(!mtx_unblock_lock.open_or_create(aux_str.c_str(), perm))
- return false;
-
- //All ok, commit data
- m_condition_data.m_sem_block_queue.swap(sem_block_queue);
- m_condition_data.m_sem_block_lock.swap(sem_block_lock);
- m_condition_data.m_mtx_unblock_lock.swap(mtx_unblock_lock);
- return true;
- }
-
- virtual void close()
- {
- m_condition_data.m_sem_block_queue.close();
- m_condition_data.m_sem_block_lock.close();
- m_condition_data.m_mtx_unblock_lock.close();
- m_condition_data.m_nwaiters_blocked = 0;
- m_condition_data.m_nwaiters_gone = 0;
- m_condition_data.m_nwaiters_to_unblock = 0;
- }
-
- virtual ~named_cond_callbacks()
- {}
-
- private:
- condition_data &m_condition_data;
- };
-
- windows_named_sync m_named_sync;
- /// @endcond
-};
-
-inline windows_named_condition::~windows_named_condition()
-{
- named_cond_callbacks callbacks(m_condition_data);
- m_named_sync.close(callbacks);
-}
-
-inline void windows_named_condition::dont_close_on_destruction()
-{}
-
-inline windows_named_condition::windows_named_condition
- (create_only_t, const char *name, const permissions &perm)
- : m_condition_data()
-{
- named_cond_callbacks callbacks(m_condition_data);
- m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
-}
-
-inline windows_named_condition::windows_named_condition
- (open_or_create_t, const char *name, const permissions &perm)
- : m_condition_data()
-{
- named_cond_callbacks callbacks(m_condition_data);
- m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
-}
-
-inline windows_named_condition::windows_named_condition(open_only_t, const char *name)
- : m_condition_data()
-{
- named_cond_callbacks callbacks(m_condition_data);
- m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
-}
-
-inline void windows_named_condition::notify_one()
-{ algorithm_type::signal(m_condition_data, false); }
-
-inline void windows_named_condition::notify_all()
-{ algorithm_type::signal(m_condition_data, true); }
-
-template<class InterprocessMutex>
-inline void windows_named_condition::do_wait(InterprocessMutex &mut)
-{ algorithm_type::wait(m_condition_data, false, boost::posix_time::ptime(), mut); }
-
-template<class InterprocessMutex>
-inline bool windows_named_condition::do_timed_wait
- (const boost::posix_time::ptime &abs_time, InterprocessMutex &mut)
-{ return algorithm_type::wait(m_condition_data, true, abs_time, mut); }
-
-template <typename L>
-inline void windows_named_condition::wait(L& lock)
-{
- if (!lock)
- throw lock_exception();
- this->do_wait(*lock.mutex());
-}
-
-template <typename L, typename Pr>
-inline void windows_named_condition::wait(L& lock, Pr pred)
-{
- if (!lock)
- throw lock_exception();
- while (!pred())
- this->do_wait(*lock.mutex());
-}
-
-template <typename L>
-inline bool windows_named_condition::timed_wait
- (L& lock, const boost::posix_time::ptime &abs_time)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait(lock);
- return true;
- }
- if (!lock)
- throw lock_exception();
- return this->do_timed_wait(abs_time, *lock.mutex());
-}
-
-template <typename L, typename Pr>
-inline bool windows_named_condition::timed_wait
- (L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
-{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait(lock, pred);
- return true;
- }
- if (!lock)
- throw lock_exception();
-
- while (!pred()){
- if(!this->do_timed_wait(abs_time, *lock.mutex())){
- return pred();
- }
- }
- return true;
-}
-
-inline bool windows_named_condition::remove(const char *name)
-{
- return windows_named_sync::remove(name);
-}
+typedef windows_named_condition_any windows_named_condition;
} //namespace ipcdetail {
} //namespace interprocess {
diff --git a/boost/interprocess/sync/windows/named_condition_any.hpp b/boost/interprocess/sync/windows/named_condition_any.hpp
new file mode 100644
index 0000000..fc2a7fc
--- /dev/null
+++ b/boost/interprocess/sync/windows/named_condition_any.hpp
@@ -0,0 +1,240 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2012. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/permissions.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/windows/named_sync.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
+#include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+class windows_named_condition_any
+{
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //Non-copyable
+ windows_named_condition_any();
+ windows_named_condition_any(const windows_named_condition_any &);
+ windows_named_condition_any &operator=(const windows_named_condition_any &);
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
+ public:
+ windows_named_condition_any
+ (create_only_t, const char *name, const permissions &perm)
+ : m_condition_data()
+ {
+ named_cond_callbacks callbacks(m_condition_data.get_members());
+ m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
+ }
+
+ windows_named_condition_any
+ (open_or_create_t, const char *name, const permissions &perm)
+ : m_condition_data()
+ {
+ named_cond_callbacks callbacks(m_condition_data.get_members());
+ m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
+ }
+
+ windows_named_condition_any(open_only_t, const char *name)
+ : m_condition_data()
+ {
+ named_cond_callbacks callbacks(m_condition_data.get_members());
+ m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
+ }
+
+ ~windows_named_condition_any()
+ {
+ named_cond_callbacks callbacks(m_condition_data.get_members());
+ m_named_sync.close(callbacks);
+ }
+
+ void notify_one()
+ { m_condition_data.notify_one(); }
+
+ void notify_all()
+ { m_condition_data.notify_all(); }
+
+ template <typename L>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
+ { return m_condition_data.timed_wait(lock, abs_time); }
+
+ template <typename L, typename Pr>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+ { return m_condition_data.timed_wait(lock, abs_time, pred); }
+
+ template <typename L>
+ void wait(L& lock)
+ { m_condition_data.wait(lock); }
+
+ template <typename L, typename Pr>
+ void wait(L& lock, Pr pred)
+ { m_condition_data.wait(lock, pred); }
+
+ static bool remove(const char *name)
+ { return windows_named_sync::remove(name); }
+
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ private:
+
+ void dont_close_on_destruction()
+ {}
+
+ friend class interprocess_tester;
+
+ struct condition_data
+ {
+ typedef boost::int32_t integer_type;
+ typedef winapi_semaphore_wrapper semaphore_type;
+ typedef winapi_mutex_wrapper mutex_type;
+
+ integer_type &get_nwaiters_blocked()
+ { return m_nwaiters_blocked; }
+
+ integer_type &get_nwaiters_gone()
+ { return m_nwaiters_gone; }
+
+ integer_type &get_nwaiters_to_unblock()
+ { return m_nwaiters_to_unblock; }
+
+ semaphore_type &get_sem_block_queue()
+ { return m_sem_block_queue; }
+
+ semaphore_type &get_sem_block_lock()
+ { return m_sem_block_lock; }
+
+ mutex_type &get_mtx_unblock_lock()
+ { return m_mtx_unblock_lock; }
+
+ integer_type m_nwaiters_blocked;
+ integer_type m_nwaiters_gone;
+ integer_type m_nwaiters_to_unblock;
+ winapi_semaphore_wrapper m_sem_block_queue;
+ winapi_semaphore_wrapper m_sem_block_lock;
+ winapi_mutex_wrapper m_mtx_unblock_lock;
+ };
+
+ class named_cond_callbacks : public windows_named_sync_interface
+ {
+ typedef __int64 sem_count_t;
+ mutable sem_count_t sem_counts [2];
+
+ public:
+ named_cond_callbacks(condition_data &cond_data)
+ : m_condition_data(cond_data)
+ {}
+
+ virtual std::size_t get_data_size() const
+ { return sizeof(sem_counts); }
+
+ virtual const void *buffer_with_final_data_to_file()
+ {
+ sem_counts[0] = m_condition_data.m_sem_block_queue.value();
+ sem_counts[1] = m_condition_data.m_sem_block_lock.value();
+ return &sem_counts;
+ }
+
+ virtual const void *buffer_with_init_data_to_file()
+ {
+ sem_counts[0] = 0;
+ sem_counts[1] = 1;
+ return &sem_counts;
+ }
+
+ virtual void *buffer_to_store_init_data_from_file()
+ { return &sem_counts; }
+
+ virtual bool open(create_enum_t, const char *id_name)
+ {
+ m_condition_data.m_nwaiters_blocked = 0;
+ m_condition_data.m_nwaiters_gone = 0;
+ m_condition_data.m_nwaiters_to_unblock = 0;
+
+ //Now open semaphores and mutex.
+ //Use local variables + swap to guarantee consistent
+ //initialization and cleanup in case any opening fails
+ permissions perm;
+ perm.set_unrestricted();
+ std::string aux_str = "Global\\bipc.cond.";
+ aux_str += id_name;
+ std::size_t pos = aux_str.size();
+
+ //sem_block_queue
+ aux_str += "_bq";
+ winapi_semaphore_wrapper sem_block_queue;
+ bool created;
+ if(!sem_block_queue.open_or_create
+ (aux_str.c_str(), sem_counts[0], winapi_semaphore_wrapper::MaxCount, perm, created))
+ return false;
+ aux_str.erase(pos);
+
+ //sem_block_lock
+ aux_str += "_bl";
+ winapi_semaphore_wrapper sem_block_lock;
+ if(!sem_block_lock.open_or_create
+ (aux_str.c_str(), sem_counts[1], winapi_semaphore_wrapper::MaxCount, perm, created))
+ return false;
+ aux_str.erase(pos);
+
+ //mtx_unblock_lock
+ aux_str += "_ul";
+ winapi_mutex_wrapper mtx_unblock_lock;
+ if(!mtx_unblock_lock.open_or_create(aux_str.c_str(), perm))
+ return false;
+
+ //All ok, commit data
+ m_condition_data.m_sem_block_queue.swap(sem_block_queue);
+ m_condition_data.m_sem_block_lock.swap(sem_block_lock);
+ m_condition_data.m_mtx_unblock_lock.swap(mtx_unblock_lock);
+ return true;
+ }
+
+ virtual void close()
+ {
+ m_condition_data.m_sem_block_queue.close();
+ m_condition_data.m_sem_block_lock.close();
+ m_condition_data.m_mtx_unblock_lock.close();
+ m_condition_data.m_nwaiters_blocked = 0;
+ m_condition_data.m_nwaiters_gone = 0;
+ m_condition_data.m_nwaiters_to_unblock = 0;
+ }
+
+ virtual ~named_cond_callbacks()
+ {}
+
+ private:
+ condition_data &m_condition_data;
+ };
+
+ windows_named_sync m_named_sync;
+ ipcdetail::condition_8a_wrapper<condition_data> m_condition_data;
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+};
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
diff --git a/boost/interprocess/sync/windows/named_mutex.hpp b/boost/interprocess/sync/windows/named_mutex.hpp
index 8ea6b3e..9d57385 100644
--- a/boost/interprocess/sync/windows/named_mutex.hpp
+++ b/boost/interprocess/sync/windows/named_mutex.hpp
@@ -10,7 +10,7 @@
#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_MUTEX_HPP
#define BOOST_INTERPROCESS_WINDOWS_NAMED_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -35,13 +35,13 @@ namespace ipcdetail {
class windows_named_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
windows_named_mutex();
windows_named_mutex(const windows_named_mutex &);
windows_named_mutex &operator=(const windows_named_mutex &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
windows_named_mutex(create_only_t, const char *name, const permissions &perm = permissions());
@@ -59,7 +59,7 @@ class windows_named_mutex
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class interprocess_tester;
void dont_close_on_destruction();
@@ -106,7 +106,7 @@ class windows_named_mutex
private:
winapi_mutex_wrapper& m_mtx_wrapper;
};
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
inline windows_named_mutex::~windows_named_mutex()
diff --git a/boost/interprocess/sync/windows/named_recursive_mutex.hpp b/boost/interprocess/sync/windows/named_recursive_mutex.hpp
index cb2ef79..695c44a 100644
--- a/boost/interprocess/sync/windows/named_recursive_mutex.hpp
+++ b/boost/interprocess/sync/windows/named_recursive_mutex.hpp
@@ -10,7 +10,7 @@
#ifndef BOOST_INTERPROCESS_WINDOWS_RECURSIVE_NAMED_MUTEX_HPP
#define BOOST_INTERPROCESS_WINDOWS_RECURSIVE_NAMED_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -27,13 +27,13 @@ class windows_named_recursive_mutex
//Windows mutexes based on CreateMutex are already recursive...
: public windows_named_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
windows_named_recursive_mutex();
windows_named_recursive_mutex(const windows_named_mutex &);
windows_named_recursive_mutex &operator=(const windows_named_mutex &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
windows_named_recursive_mutex(create_only_t, const char *name, const permissions &perm = permissions())
diff --git a/boost/interprocess/sync/windows/named_semaphore.hpp b/boost/interprocess/sync/windows/named_semaphore.hpp
index 8f48d4d..7adf91b 100644
--- a/boost/interprocess/sync/windows/named_semaphore.hpp
+++ b/boost/interprocess/sync/windows/named_semaphore.hpp
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_SEMAPHORE_HPP
#define BOOST_INTERPROCESS_WINDOWS_NAMED_SEMAPHORE_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -32,13 +32,13 @@ namespace ipcdetail {
class windows_named_semaphore
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
windows_named_semaphore();
windows_named_semaphore(const windows_named_semaphore &);
windows_named_semaphore &operator=(const windows_named_semaphore &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
windows_named_semaphore(create_only_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
@@ -56,7 +56,7 @@ class windows_named_semaphore
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class interprocess_tester;
void dont_close_on_destruction();
@@ -109,7 +109,7 @@ class windows_named_semaphore
winapi_semaphore_wrapper& m_sem_wrapper;
};
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
inline windows_named_semaphore::~windows_named_semaphore()
diff --git a/boost/interprocess/sync/windows/named_sync.hpp b/boost/interprocess/sync/windows/named_sync.hpp
index 41f299f..5af7a32 100644
--- a/boost/interprocess/sync/windows/named_sync.hpp
+++ b/boost/interprocess/sync/windows/named_sync.hpp
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
#define BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -19,12 +19,12 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/permissions.hpp>
-#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
+#include <boost/interprocess/detail/shared_dir_helpers.hpp>
#include <boost/interprocess/sync/windows/sync_utils.hpp>
#include <boost/interprocess/errors.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <string>
-#include <cassert>
+#include <boost/assert.hpp>
namespace boost {
namespace interprocess {
@@ -47,12 +47,12 @@ inline windows_named_sync_interface::~windows_named_sync_interface()
class windows_named_sync
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
windows_named_sync(const windows_named_sync &);
windows_named_sync &operator=(const windows_named_sync &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
windows_named_sync();
@@ -61,11 +61,11 @@ class windows_named_sync
static bool remove(const char *name);
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
void *m_file_hnd;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
inline windows_named_sync::windows_named_sync()
@@ -106,7 +106,7 @@ inline void windows_named_sync::open_or_create
//Use a file to emulate POSIX lifetime semantics. After this logic
//we'll obtain the ID of the native handle to open in aux_str
{
- create_tmp_and_clean_old_and_get_filename(name, aux_str);
+ create_shared_dir_cleaning_old_and_get_filepath(name, aux_str);
//Create a file with required permissions.
m_file_hnd = winapi::create_file
( aux_str.c_str()
@@ -145,7 +145,7 @@ inline void windows_named_sync::open_or_create
success = true;
}
winapi::get_file_size(m_file_hnd, filesize);
- assert(std::size_t(filesize) == sizeof_file_info);
+ BOOST_ASSERT(std::size_t(filesize) == sizeof_file_info);
}
else{
void *buf = sync_interface.buffer_to_store_init_data_from_file();
@@ -198,7 +198,7 @@ inline bool windows_named_sync::remove(const char *name)
try{
//Make sure a temporary path is created for shared memory
std::string semfile;
- ipcdetail::tmp_filename(name, semfile);
+ ipcdetail::shared_filepath(name, semfile);
return winapi::unlink_file(semfile.c_str());
}
catch(...){
diff --git a/boost/interprocess/sync/windows/recursive_mutex.hpp b/boost/interprocess/sync/windows/recursive_mutex.hpp
index 9565cb6..55a8385 100644
--- a/boost/interprocess/sync/windows/recursive_mutex.hpp
+++ b/boost/interprocess/sync/windows/recursive_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_RECURSIVE_MUTEX_HPP
#define BOOST_INTERPROCESS_DETAIL_WINDOWS_RECURSIVE_MUTEX_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
diff --git a/boost/interprocess/sync/windows/semaphore.hpp b/boost/interprocess/sync/windows/semaphore.hpp
index af336df..7fdbc41 100644
--- a/boost/interprocess/sync/windows/semaphore.hpp
+++ b/boost/interprocess/sync/windows/semaphore.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_SEMAPHORE_HPP
#define BOOST_INTERPROCESS_DETAIL_WINDOWS_SEMAPHORE_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -23,6 +23,7 @@
#include <boost/interprocess/sync/windows/sync_utils.hpp>
#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
#include <boost/interprocess/exceptions.hpp>
+#include <boost/assert.hpp>
namespace boost {
@@ -56,8 +57,8 @@ inline windows_semaphore::windows_semaphore(unsigned int initialCount)
bool open_or_created;
handles.obtain_semaphore(this->id_, initialCount, &open_or_created);
//The semaphore must be created, never opened
- assert(open_or_created);
- assert(open_or_created && winapi::get_last_error() != winapi::error_already_exists);
+ BOOST_ASSERT(open_or_created);
+ BOOST_ASSERT(open_or_created && winapi::get_last_error() != winapi::error_already_exists);
(void)open_or_created;
}
diff --git a/boost/interprocess/sync/windows/sync_utils.hpp b/boost/interprocess/sync/windows/sync_utils.hpp
index 0281da1..7e54cc3 100644
--- a/boost/interprocess/sync/windows/sync_utils.hpp
+++ b/boost/interprocess/sync/windows/sync_utils.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2012. 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)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_DETAIL_SYNC_UTILS_HPP
#define BOOST_INTERPROCESS_DETAIL_SYNC_UTILS_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -23,7 +23,13 @@
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
-#include <boost/unordered/unordered_map.hpp>
+
+//Shield against external warnings
+#include <boost/interprocess/detail/config_external_begin.hpp>
+ #include <boost/unordered/unordered_map.hpp>
+#include <boost/interprocess/detail/config_external_end.hpp>
+
+
#include <boost/container/map.hpp>
#include <cstddef>
@@ -71,7 +77,7 @@ class sync_id
internal_type &internal_pod()
{ return rand_; }
- const void *map_addr() const
+ const void *map_address() const
{ return map_addr_; }
friend std::size_t hash_value(const sync_id &m)
@@ -94,7 +100,7 @@ class sync_handles
struct address_less
{
bool operator()(sync_id const * const l, sync_id const * const r) const
- { return l->map_addr() < r->map_addr(); }
+ { return l->map_address() < r->map_address(); }
};
typedef boost::unordered_map<sync_id, void*> umap_type;
@@ -156,12 +162,15 @@ class sync_handles
umap_type::value_type v(id, (void*)0);
scoped_lock<spin_mutex> lock(mtx_);
umap_type::iterator it = umap_.insert(v).first;
- map_[&it->first] = it;
void *&hnd_val = it->second;
if(!hnd_val){
+ map_[&it->first] = it;
hnd_val = open_or_create_mutex(id);
if(popen_created) *popen_created = true;
}
+ else if(popen_created){
+ *popen_created = false;
+ }
return hnd_val;
}
@@ -170,12 +179,15 @@ class sync_handles
umap_type::value_type v(id, (void*)0);
scoped_lock<spin_mutex> lock(mtx_);
umap_type::iterator it = umap_.insert(v).first;
- map_[&it->first] = it;
void *&hnd_val = it->second;
if(!hnd_val){
+ map_[&it->first] = it;
hnd_val = open_or_create_semaphore(id, initial_count);
if(popen_created) *popen_created = true;
}
+ else if(popen_created){
+ *popen_created = false;
+ }
return hnd_val;
}
@@ -195,13 +207,13 @@ class sync_handles
void destroy_syncs_in_range(const void *addr, std::size_t size)
{
- sync_id low_id(addr);
- sync_id hig_id(static_cast<const char*>(addr)+size);
+ const sync_id low_id(addr);
+ const sync_id hig_id(static_cast<const char*>(addr)+size);
scoped_lock<spin_mutex> lock(mtx_);
map_type::iterator itlow(map_.lower_bound(&low_id)),
ithig(map_.lower_bound(&hig_id));
while(itlow != ithig){
- void *hnd = umap_[*itlow->first];
+ void * const hnd = umap_[*itlow->first];
winapi::close_handle(hnd);
umap_.erase(*itlow->first);
itlow = map_.erase(itlow);
diff --git a/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp b/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp
index 0be9601..f7b78a9 100644
--- a/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp
+++ b/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_DETAIL_WINAPI_MUTEX_WRAPPER_HPP
#define BOOST_INTERPROCESS_DETAIL_WINAPI_MUTEX_WRAPPER_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -21,6 +21,7 @@
#include <boost/interprocess/permissions.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/windows/winapi_wrapper_common.hpp>
#include <boost/interprocess/errors.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <limits>
@@ -31,12 +32,12 @@ namespace ipcdetail {
class winapi_mutex_functions
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
winapi_mutex_functions(const winapi_mutex_functions &);
winapi_mutex_functions &operator=(const winapi_mutex_functions &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
winapi_mutex_functions(void *mtx_hnd)
@@ -44,73 +45,39 @@ class winapi_mutex_functions
{}
void unlock()
- {
- winapi::release_mutex(m_mtx_hnd);
- }
+ { winapi::release_mutex(m_mtx_hnd); }
void lock()
- {
- if(winapi::wait_for_single_object(m_mtx_hnd, winapi::infinite_time) != winapi::wait_object_0){
- error_info err = system_error_code();
- throw interprocess_exception(err);
- }
- }
+ { return winapi_wrapper_wait_for_single_object(m_mtx_hnd); }
bool try_lock()
- {
- unsigned long ret = winapi::wait_for_single_object(m_mtx_hnd, 0);
- if(ret == winapi::wait_object_0){
- return true;
- }
- else if(ret == winapi::wait_timeout){
- return false;
- }
- else{
- error_info err = system_error_code();
- throw interprocess_exception(err);
- }
- }
+ { return winapi_wrapper_try_wait_for_single_object(m_mtx_hnd); }
bool timed_lock(const boost::posix_time::ptime &abs_time)
- {
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
+ { return winapi_wrapper_timed_wait_for_single_object(m_mtx_hnd, abs_time); }
- unsigned long ret = winapi::wait_for_single_object
- (m_mtx_hnd, (abs_time - microsec_clock::universal_time()).total_milliseconds());
- if(ret == winapi::wait_object_0){
- return true;
- }
- else if(ret == winapi::wait_timeout){
- return false;
- }
- else{
- error_info err = system_error_code();
- throw interprocess_exception(err);
- }
- }
-
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
protected:
void *m_mtx_hnd;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
//Swappable mutex wrapper
class winapi_mutex_wrapper
: public winapi_mutex_functions
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
winapi_mutex_wrapper(const winapi_mutex_wrapper &);
winapi_mutex_wrapper &operator=(const winapi_mutex_wrapper &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
+ //Note that Windows API does not return winapi::invalid_handle_value
+ //when failing to create/open a mutex, but a nullptr
public:
- winapi_mutex_wrapper(void *mtx_hnd = winapi::invalid_handle_value)
+ winapi_mutex_wrapper(void *mtx_hnd = 0)
: winapi_mutex_functions(mtx_hnd)
{}
@@ -120,7 +87,7 @@ class winapi_mutex_wrapper
void *release()
{
void *hnd = m_mtx_hnd;
- m_mtx_hnd = winapi::invalid_handle_value;
+ m_mtx_hnd = 0;
return hnd;
}
@@ -129,24 +96,24 @@ class winapi_mutex_wrapper
bool open_or_create(const char *name, const permissions &perm)
{
- if(m_mtx_hnd == winapi::invalid_handle_value){
+ if(m_mtx_hnd == 0){
m_mtx_hnd = winapi::open_or_create_mutex
( name
, false
, (winapi::interprocess_security_attributes*)perm.get_permissions()
);
- return m_mtx_hnd != winapi::invalid_handle_value;
+ return m_mtx_hnd != 0;
}
else{
return false;
}
- }
+ }
void close()
{
- if(m_mtx_hnd != winapi::invalid_handle_value){
+ if(m_mtx_hnd != 0){
winapi::close_handle(m_mtx_hnd);
- m_mtx_hnd = winapi::invalid_handle_value;
+ m_mtx_hnd = 0;
}
}
diff --git a/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp b/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp
index 2dd7845..f64d506 100644
--- a/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp
+++ b/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp
@@ -11,7 +11,7 @@
#ifndef BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
#define BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined(_MSC_VER)
# pragma once
#endif
@@ -21,6 +21,7 @@
#include <boost/interprocess/permissions.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/windows/winapi_wrapper_common.hpp>
#include <boost/interprocess/errors.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <limits>
@@ -31,12 +32,12 @@ namespace ipcdetail {
class winapi_semaphore_functions
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
winapi_semaphore_functions(const winapi_semaphore_functions &);
winapi_semaphore_functions &operator=(const winapi_semaphore_functions &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
winapi_semaphore_functions(void *hnd)
@@ -50,69 +51,34 @@ class winapi_semaphore_functions
}
void wait()
- {
- if(winapi::wait_for_single_object(m_sem_hnd, winapi::infinite_time) != winapi::wait_object_0){
- error_info err = system_error_code();
- throw interprocess_exception(err);
- }
- }
+ { return winapi_wrapper_wait_for_single_object(m_sem_hnd); }
bool try_wait()
- {
- unsigned long ret = winapi::wait_for_single_object(m_sem_hnd, 0);
- if(ret == winapi::wait_object_0){
- return true;
- }
- else if(ret == winapi::wait_timeout){
- return false;
- }
- else{
- error_info err = system_error_code();
- throw interprocess_exception(err);
- }
- }
+ { return winapi_wrapper_try_wait_for_single_object(m_sem_hnd); }
bool timed_wait(const boost::posix_time::ptime &abs_time)
- {
- if(abs_time == boost::posix_time::pos_infin){
- this->wait();
- return true;
- }
-
- unsigned long ret = winapi::wait_for_single_object
- (m_sem_hnd, (abs_time - microsec_clock::universal_time()).total_milliseconds());
- if(ret == winapi::wait_object_0){
- return true;
- }
- else if(ret == winapi::wait_timeout){
- return false;
- }
- else{
- error_info err = system_error_code();
- throw interprocess_exception(err);
- }
- }
+ { return winapi_wrapper_timed_wait_for_single_object(m_sem_hnd, abs_time); }
long value() const
{
- long count, limit;
- if(!winapi::get_semaphore_info(m_sem_hnd, count, limit))
+ long l_count, l_limit;
+ if(!winapi::get_semaphore_info(m_sem_hnd, l_count, l_limit))
return 0;
- return count;
+ return l_count;
}
long limit() const
{
- long count, limit;
- if(!winapi::get_semaphore_info(m_sem_hnd, count, limit))
+ long l_count, l_limit;
+ if(!winapi::get_semaphore_info(m_sem_hnd, l_count, l_limit))
return 0;
- return limit;
+ return l_limit;
}
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
protected:
void *m_sem_hnd;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
@@ -136,7 +102,7 @@ class winapi_semaphore_wrapper
{ this->close(); }
void *release()
- {
+ {
void *hnd = m_sem_hnd;
m_sem_hnd = winapi::invalid_handle_value;
return hnd;
diff --git a/boost/interprocess/sync/windows/winapi_wrapper_common.hpp b/boost/interprocess/sync/windows/winapi_wrapper_common.hpp
new file mode 100644
index 0000000..ccf2d65
--- /dev/null
+++ b/boost/interprocess/sync/windows/winapi_wrapper_common.hpp
@@ -0,0 +1,93 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2012. 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/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_DETAIL_WINAPI_WRAPPER_COMMON_HPP
+#define BOOST_INTERPROCESS_DETAIL_WINAPI_WRAPPER_COMMON_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/detail/win32_api.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/errors.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+inline void winapi_wrapper_wait_for_single_object(void *handle)
+{
+ unsigned long ret = winapi::wait_for_single_object(handle, winapi::infinite_time);
+ if(ret != winapi::wait_object_0){
+ if(ret != winapi::wait_abandoned){
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+ else{ //Special case for orphaned mutexes
+ winapi::release_mutex(handle);
+ throw interprocess_exception(owner_dead_error);
+ }
+ }
+}
+
+inline bool winapi_wrapper_try_wait_for_single_object(void *handle)
+{
+ unsigned long ret = winapi::wait_for_single_object(handle, 0);
+ if(ret == winapi::wait_object_0){
+ return true;
+ }
+ else if(ret == winapi::wait_timeout){
+ return false;
+ }
+ else{
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+}
+
+inline bool winapi_wrapper_timed_wait_for_single_object(void *handle, const boost::posix_time::ptime &abs_time)
+{
+ //Windows does not support infinity abs_time so check it
+ if(abs_time == boost::posix_time::pos_infin){
+ winapi_wrapper_wait_for_single_object(handle);
+ return true;
+ }
+ const boost::posix_time::ptime cur_time = microsec_clock::universal_time();
+ //Windows uses relative wait times so check for negative waits
+ //and implement as 0 wait to allow try-semantics as POSIX mandates.
+ unsigned long ret = winapi::wait_for_single_object
+ ( handle
+ , (abs_time <= cur_time) ? 0u
+ : (abs_time - cur_time).total_milliseconds()
+ );
+ if(ret == winapi::wait_object_0){
+ return true;
+ }
+ else if(ret == winapi::wait_timeout){
+ return false;
+ }
+ else{
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+}
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_DETAIL_WINAPI_MUTEX_WRAPPER_HPP
diff --git a/boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp b/boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp
index a0c3a91..b69cfbf 100644
--- a/boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp
+++ b/boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp
@@ -30,6 +30,10 @@
#ifndef BOOST_INTERPROCESS_SYNC_XSI_ADVANCED_XSI_SEMAPHORE_HPP
#define BOOST_INTERPROCESS_SYNC_XSI_ADVANCED_XSI_SEMAPHORE_HPP
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
diff --git a/boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp b/boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp
index 266e7c5..69ad34c 100644
--- a/boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp
+++ b/boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2011-2012. 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)
//
@@ -10,6 +10,10 @@
#ifndef BOOST_INTERPROCESS_SYNC_XSI_SIMPLE_XSI_SEMAPHORE_HPP
#define BOOST_INTERPROCESS_SYNC_XSI_SIMPLE_XSI_SEMAPHORE_HPP
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
/*
* Provide an simpler and easier to understand interface to the System V
* semaphore system calls. There are 7 routines available to the user:
diff --git a/boost/interprocess/sync/xsi/xsi_named_mutex.hpp b/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
index 485b1ac..1c4ee78 100644
--- a/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
+++ b/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2009-2012. 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)
//
@@ -11,6 +11,10 @@
#ifndef BOOST_INTERPROCESS_XSI_XSI_NAMED_MUTEX_HPP
#define BOOST_INTERPROCESS_XSI_XSI_NAMED_MUTEX_HPP
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
@@ -18,7 +22,7 @@
#error "This header can't be used in Windows operating systems"
#endif
-#include <boost/move/move.hpp>
+#include <boost/move/utility_core.hpp>
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/utilities.hpp>
@@ -42,11 +46,11 @@ namespace interprocess {
//!that undoes the operation if the process crashes.
class xsi_named_mutex
{
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable and non-assignable
xsi_named_mutex(xsi_named_mutex &);
xsi_named_mutex &operator=(xsi_named_mutex &);
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
BOOST_MOVABLE_BUT_NOT_COPYABLE(xsi_named_mutex)
@@ -72,10 +76,10 @@ class xsi_named_mutex
//!After the call, "moved" does not represent any named mutex.
//!Does not throw
xsi_named_mutex &operator=(BOOST_RV_REF(xsi_named_mutex) moved)
- {
+ {
xsi_named_mutex tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
//!Swaps two xsi_named_mutex. Does not throw
@@ -105,7 +109,7 @@ class xsi_named_mutex
void unlock();
- /// @cond
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
//!Closes a previously opened file mapping. Never throws.
@@ -121,10 +125,10 @@ class xsi_named_mutex
boost::uint8_t m_id;
int m_perm;
std::string m_path;
- /// @endcond
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
-/// @cond
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline xsi_named_mutex::xsi_named_mutex()
: m_semid(-1), m_key(-1), m_id(0), m_perm(0), m_path()
@@ -142,7 +146,7 @@ inline void xsi_named_mutex::swap(xsi_named_mutex &other)
std::swap(m_id, other.m_id);
std::swap(m_semid, other.m_semid);
std::swap(m_perm, other.m_perm);
- m_path.swap(other.m_path);
+ m_path.swap(other.m_path);
}
inline mapping_handle_t xsi_named_mutex::get_mapping_handle() const
@@ -218,7 +222,7 @@ inline bool xsi_named_mutex::remove()
return false;
}
-///@endcond
+#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
} //namespace interprocess {
} //namespace boost {