summaryrefslogtreecommitdiff
path: root/boost/interprocess/sync
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess/sync')
-rw-r--r--boost/interprocess/sync/detail/condition_algorithm_8a.hpp316
-rw-r--r--boost/interprocess/sync/file_lock.hpp32
-rw-r--r--boost/interprocess/sync/interprocess_condition.hpp22
-rw-r--r--boost/interprocess/sync/interprocess_mutex.hpp12
-rw-r--r--boost/interprocess/sync/interprocess_recursive_mutex.hpp12
-rw-r--r--boost/interprocess/sync/interprocess_semaphore.hpp14
-rw-r--r--boost/interprocess/sync/interprocess_upgradable_mutex.hpp100
-rw-r--r--boost/interprocess/sync/mutex_family.hpp4
-rw-r--r--boost/interprocess/sync/named_condition.hpp34
-rw-r--r--boost/interprocess/sync/named_mutex.hpp33
-rw-r--r--boost/interprocess/sync/named_recursive_mutex.hpp20
-rw-r--r--boost/interprocess/sync/named_semaphore.hpp21
-rw-r--r--boost/interprocess/sync/named_upgradable_mutex.hpp64
-rw-r--r--boost/interprocess/sync/posix/condition.hpp18
-rw-r--r--boost/interprocess/sync/posix/mutex.hpp6
-rw-r--r--boost/interprocess/sync/posix/pthread_helpers.hpp22
-rw-r--r--boost/interprocess/sync/posix/recursive_mutex.hpp4
-rw-r--r--boost/interprocess/sync/posix/semaphore_wrapper.hpp8
-rw-r--r--boost/interprocess/sync/scoped_lock.hpp38
-rw-r--r--boost/interprocess/sync/sharable_lock.hpp20
-rw-r--r--boost/interprocess/sync/shm/named_condition.hpp47
-rw-r--r--boost/interprocess/sync/shm/named_creation_functor.hpp2
-rw-r--r--boost/interprocess/sync/shm/named_mutex.hpp6
-rw-r--r--boost/interprocess/sync/shm/named_recursive_mutex.hpp4
-rw-r--r--boost/interprocess/sync/shm/named_upgradable_mutex.hpp64
-rw-r--r--boost/interprocess/sync/spin/condition.hpp32
-rw-r--r--boost/interprocess/sync/spin/mutex.hpp8
-rw-r--r--boost/interprocess/sync/spin/recursive_mutex.hpp8
-rw-r--r--boost/interprocess/sync/upgradable_lock.hpp20
-rw-r--r--boost/interprocess/sync/windows/condition.hpp315
-rw-r--r--boost/interprocess/sync/windows/mutex.hpp63
-rw-r--r--boost/interprocess/sync/windows/named_condition.hpp334
-rw-r--r--boost/interprocess/sync/windows/named_mutex.hpp175
-rw-r--r--boost/interprocess/sync/windows/named_recursive_mutex.hpp58
-rw-r--r--boost/interprocess/sync/windows/named_semaphore.hpp178
-rw-r--r--boost/interprocess/sync/windows/named_sync.hpp215
-rw-r--r--boost/interprocess/sync/windows/semaphore.hpp63
-rw-r--r--boost/interprocess/sync/windows/sync_utils.hpp117
-rw-r--r--boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp163
-rw-r--r--boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp198
-rw-r--r--boost/interprocess/sync/xsi/xsi_named_mutex.hpp16
41 files changed, 2175 insertions, 711 deletions
diff --git a/boost/interprocess/sync/detail/condition_algorithm_8a.hpp b/boost/interprocess/sync/detail/condition_algorithm_8a.hpp
new file mode 100644
index 0000000000..eaad671cdf
--- /dev/null
+++ b/boost/interprocess/sync/detail/condition_algorithm_8a.hpp
@@ -0,0 +1,316 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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_ALGORITHM_8A_HPP
+#define BOOST_INTERPROCESS_DETAIL_CONDITION_ALGORITHM_8A_HPP
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+//
+// Condition variable algorithm taken from pthreads-win32 discussion.
+//
+// The algorithm was developed by Alexander Terekhov in colaboration with
+// Louis Thomas.
+//
+// Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
+//
+// semBlockLock - bin.semaphore
+// semBlockQueue - semaphore
+// mtxExternal - mutex or CS
+// mtxUnblockLock - mutex or CS
+// nWaitersGone - int
+// nWaitersBlocked - int
+// nWaitersToUnblock - int
+//
+// wait( timeout ) {
+//
+// [auto: register int result ] // error checking omitted
+// [auto: register int nSignalsWasLeft ]
+// [auto: register int nWaitersWasGone ]
+//
+// sem_wait( semBlockLock );
+// nWaitersBlocked++;
+// sem_post( semBlockLock );
+//
+// unlock( mtxExternal );
+// bTimedOut = sem_wait( semBlockQueue,timeout );
+//
+// lock( mtxUnblockLock );
+// if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
+// if ( bTimedOut ) { // timeout (or canceled)
+// if ( 0 != nWaitersBlocked ) {
+// nWaitersBlocked--;
+// }
+// else {
+// nWaitersGone++; // count spurious wakeups.
+// }
+// }
+// if ( 0 == --nWaitersToUnblock ) {
+// if ( 0 != nWaitersBlocked ) {
+// sem_post( semBlockLock ); // open the gate.
+// nSignalsWasLeft = 0; // do not open the gate
+// // below again.
+// }
+// else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
+// nWaitersGone = 0;
+// }
+// }
+// }
+// else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
+// // spurious semaphore :-)
+// sem_wait( semBlockLock );
+// nWaitersBlocked -= nWaitersGone; // something is going on here
+// // - test of timeouts? :-)
+// sem_post( semBlockLock );
+// nWaitersGone = 0;
+// }
+// unlock( mtxUnblockLock );
+//
+// if ( 1 == nSignalsWasLeft ) {
+// if ( 0 != nWaitersWasGone ) {
+// // sem_adjust( semBlockQueue,-nWaitersWasGone );
+// while ( nWaitersWasGone-- ) {
+// sem_wait( semBlockQueue ); // better now than spurious later
+// }
+// } sem_post( semBlockLock ); // open the gate
+// }
+//
+// lock( mtxExternal );
+//
+// return ( bTimedOut ) ? ETIMEOUT : 0;
+// }
+//
+// signal(bAll) {
+//
+// [auto: register int result ]
+// [auto: register int nSignalsToIssue]
+//
+// lock( mtxUnblockLock );
+//
+// if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
+// if ( 0 == nWaitersBlocked ) { // NO-OP
+// return unlock( mtxUnblockLock );
+// }
+// if (bAll) {
+// nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
+// nWaitersBlocked = 0;
+// }
+// else {
+// nSignalsToIssue = 1;
+// nWaitersToUnblock++;
+// nWaitersBlocked--;
+// }
+// }
+// else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+// sem_wait( semBlockLock ); // close the gate
+// if ( 0 != nWaitersGone ) {
+// nWaitersBlocked -= nWaitersGone;
+// nWaitersGone = 0;
+// }
+// if (bAll) {
+// nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
+// nWaitersBlocked = 0;
+// }
+// else {
+// nSignalsToIssue = nWaitersToUnblock = 1;
+// nWaitersBlocked--;
+// }
+// }
+// else { // NO-OP
+// return unlock( mtxUnblockLock );
+// }
+//
+// unlock( mtxUnblockLock );
+// sem_post( semBlockQueue,nSignalsToIssue );
+// return result;
+// }
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+
+// Required interface for ConditionMembers
+// class ConditionMembers
+// {
+// typedef implementation_defined semaphore_type;
+// typedef implementation_defined mutex_type;
+// typedef implementation_defined integer_type;
+//
+// integer_type &get_nwaiters_blocked()
+// integer_type &get_nwaiters_gone()
+// integer_type &get_nwaiters_to_unblock()
+// semaphore_type &get_sem_block_queue()
+// semaphore_type &get_sem_block_lock()
+// mutex_type &get_mtx_unblock_lock()
+// };
+//
+template<class ConditionMembers>
+class condition_algorithm_8a
+{
+ private:
+ condition_algorithm_8a();
+ ~condition_algorithm_8a();
+ condition_algorithm_8a(const condition_algorithm_8a &);
+ condition_algorithm_8a &operator=(const condition_algorithm_8a &);
+
+ typedef typename ConditionMembers::semaphore_type semaphore_type;
+ 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);
+ static void signal(ConditionMembers &data, bool broadcast);
+};
+
+template<class ConditionMembers>
+inline void condition_algorithm_8a<ConditionMembers>::signal(ConditionMembers &data, bool broadcast)
+{
+ integer_type nsignals_to_issue;
+
+ {
+ scoped_lock<mutex_type> locker(data.get_mtx_unblock_lock());
+
+ if ( 0 != data.get_nwaiters_to_unblock() ) { // the gate is closed!!!
+ if ( 0 == data.get_nwaiters_blocked() ) { // NO-OP
+ //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
+ return;
+ }
+ if (broadcast) {
+ data.get_nwaiters_to_unblock() += nsignals_to_issue = data.get_nwaiters_blocked();
+ data.get_nwaiters_blocked() = 0;
+ }
+ else {
+ nsignals_to_issue = 1;
+ data.get_nwaiters_to_unblock()++;
+ data.get_nwaiters_blocked()--;
+ }
+ }
+ else if ( data.get_nwaiters_blocked() > data.get_nwaiters_gone() ) { // HARMLESS RACE CONDITION!
+ data.get_sem_block_lock().wait(); // close the gate
+ if ( 0 != data.get_nwaiters_gone() ) {
+ data.get_nwaiters_blocked() -= data.get_nwaiters_gone();
+ data.get_nwaiters_gone() = 0;
+ }
+ if (broadcast) {
+ nsignals_to_issue = data.get_nwaiters_to_unblock() = data.get_nwaiters_blocked();
+ data.get_nwaiters_blocked() = 0;
+ }
+ else {
+ nsignals_to_issue = data.get_nwaiters_to_unblock() = 1;
+ data.get_nwaiters_blocked()--;
+ }
+ }
+ else { // NO-OP
+ //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
+ return;
+ }
+ //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
+ }
+ data.get_sem_block_queue().post(nsignals_to_issue);
+}
+
+template<class ConditionMembers>
+template<class InterprocessMutex>
+inline bool condition_algorithm_8a<ConditionMembers>::wait
+ (ConditionMembers &data, bool tout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mtxExternal)
+{
+ //Initialize to avoid warnings
+ integer_type nsignals_was_left = 0;
+ integer_type nwaiters_was_gone = 0;
+
+ data.get_sem_block_lock().wait();
+ ++data.get_nwaiters_blocked();
+ data.get_sem_block_lock().post();
+
+ struct scoped_unlock
+ {
+ InterprocessMutex & mut;
+ scoped_unlock(InterprocessMutex & m)
+ : mut(m)
+ { m.unlock(); }
+
+ ~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);
+
+ {
+ scoped_lock<mutex_type> locker(data.get_mtx_unblock_lock());
+ if ( 0 != (nsignals_was_left = data.get_nwaiters_to_unblock()) ) {
+ if ( bTimedOut ) { // timeout (or canceled)
+ if ( 0 != data.get_nwaiters_blocked() ) {
+ data.get_nwaiters_blocked()--;
+ }
+ else {
+ data.get_nwaiters_gone()++; // count spurious wakeups.
+ }
+ }
+ if ( 0 == --data.get_nwaiters_to_unblock() ) {
+ if ( 0 != data.get_nwaiters_blocked() ) {
+ data.get_sem_block_lock().post(); // open the gate.
+ nsignals_was_left = 0; // do not open the gate below again.
+ }
+ else if ( 0 != (nwaiters_was_gone = data.get_nwaiters_gone()) ) {
+ data.get_nwaiters_gone() = 0;
+ }
+ }
+ }
+ else if ( (std::numeric_limits<integer_type>::max)()/2
+ == ++data.get_nwaiters_gone() ) { // timeout/canceled or spurious semaphore :-)
+ data.get_sem_block_lock().wait();
+ data.get_nwaiters_blocked() -= data.get_nwaiters_gone(); // something is going on here - test of timeouts? :-)
+ data.get_sem_block_lock().post();
+ 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 ) {
+ // sem_adjust( data.get_sem_block_queue(),-nwaiters_was_gone );
+ while ( nwaiters_was_gone-- ) {
+ data.get_sem_block_queue().wait(); // better now than spurious later
+ }
+ }
+ data.get_sem_block_lock().post(); // open the gate
+ }
+
+ //mtxExternal.lock(); called from unlocker
+
+ return ( bTimedOut ) ? false : true;
+}
+
+} //namespace ipcdetail
+} //namespace interprocess
+} //namespace boost
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_DETAIL_CONDITION_ALGORITHM_8A_HPP
diff --git a/boost/interprocess/sync/file_lock.hpp b/boost/interprocess/sync/file_lock.hpp
index a60b814a4f..e0f75465fb 100644
--- a/boost/interprocess/sync/file_lock.hpp
+++ b/boost/interprocess/sync/file_lock.hpp
@@ -53,21 +53,21 @@ class file_lock
//!exist or there are no operating system resources.
file_lock(const char *name);
- //!Moves the ownership of "moved"'s file mapping object to *this.
- //!After the call, "moved" does not represent any file mapping object.
+ //!Moves the ownership of "moved"'s file mapping object to *this.
+ //!After the call, "moved" does not represent any file mapping object.
//!Does not throw
file_lock(BOOST_RV_REF(file_lock) moved)
: m_file_hnd(file_handle_t(ipcdetail::invalid_file()))
{ this->swap(moved); }
//!Moves the ownership of "moved"'s file mapping to *this.
- //!After the call, "moved" does not represent any file mapping.
+ //!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 +81,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,
@@ -101,12 +101,12 @@ class file_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.
+ //!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.
+ //!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();
@@ -120,21 +120,21 @@ class file_lock
//!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.
+ //! mutex this succeeds.
//!Returns: If it can acquire sharable ownership immediately returns true. If it
- //! has to wait, returns false.
+ //! 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.
+ //! 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.
+ //!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();
/// @cond
@@ -171,7 +171,7 @@ class file_lock
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;
diff --git a/boost/interprocess/sync/interprocess_condition.hpp b/boost/interprocess/sync/interprocess_condition.hpp
index b0e74fc342..9d0bea640e 100644
--- a/boost/interprocess/sync/interprocess_condition.hpp
+++ b/boost/interprocess/sync/interprocess_condition.hpp
@@ -30,9 +30,9 @@
#include <boost/interprocess/sync/posix/condition.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/condition.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/condition.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/condition.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
@@ -70,7 +70,7 @@ class interprocess_condition
//!liberating system resources.
~interprocess_condition(){}
- //!If there is a thread waiting on *this, change that
+ //!If there is a thread waiting on *this, change that
//!thread's state to ready. Otherwise there is no effect.
void notify_one()
{ m_condition.notify_one(); }
@@ -80,8 +80,8 @@ class interprocess_condition
void notify_all()
{ m_condition.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
+ //!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)
@@ -103,9 +103,9 @@ class interprocess_condition
this->do_wait(*lock.mutex());
}
- //!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,
+ //!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>
@@ -120,8 +120,8 @@ class interprocess_condition
return this->do_timed_wait(abs_time, *lock.mutex());
}
- //!The same as: while (!pred()) {
- //! if (!timed_wait(lock, abs_time)) return pred();
+ //!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)
diff --git a/boost/interprocess/sync/interprocess_mutex.hpp b/boost/interprocess/sync/interprocess_mutex.hpp
index 478cf78cc3..8110c8472b 100644
--- a/boost/interprocess/sync/interprocess_mutex.hpp
+++ b/boost/interprocess/sync/interprocess_mutex.hpp
@@ -31,9 +31,9 @@
#include <boost/interprocess/sync/posix/mutex.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/mutex.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/mutex.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
@@ -61,7 +61,7 @@ namespace interprocess {
class interprocess_condition;
-//!Wraps a interprocess_mutex that can be placed in shared memory and can be
+//!Wraps a interprocess_mutex that can be placed in shared memory and can be
//!shared between processes. Allows timed lock tries
class interprocess_mutex
{
@@ -98,9 +98,9 @@ class interprocess_mutex
//!Effects: The calling thread will try to obtain exclusive ownership of the
//! mutex if it can do so in until the specified time is reached. If the
//! mutex supports recursive locking, the mutex must be unlocked the same
- //! number of times it is locked.
+ //! number of times it is locked.
//!Returns: If the thread acquires ownership of the mutex, returns true, if
- //! the timeout expires returns false.
+ //! the timeout expires returns false.
//!Throws: interprocess_exception on error.
bool timed_lock(const boost::posix_time::ptime &abs_time);
diff --git a/boost/interprocess/sync/interprocess_recursive_mutex.hpp b/boost/interprocess/sync/interprocess_recursive_mutex.hpp
index 308819ff27..3079108645 100644
--- a/boost/interprocess/sync/interprocess_recursive_mutex.hpp
+++ b/boost/interprocess/sync/interprocess_recursive_mutex.hpp
@@ -43,9 +43,9 @@
#include <boost/interprocess/sync/posix/recursive_mutex.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/recursive_mutex.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/recursive_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/recursive_mutex.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
@@ -72,8 +72,8 @@ class mutex_traits;
namespace boost {
namespace interprocess {
-//!Wraps a interprocess_mutex that can be placed in shared memory and can be
-//!shared between processes. Allows several locking calls by the same
+//!Wraps a interprocess_mutex that can be placed in shared memory and can be
+//!shared between processes. Allows several locking calls by the same
//!process. Allows timed lock tries
class interprocess_recursive_mutex
{
@@ -99,7 +99,7 @@ class interprocess_recursive_mutex
//!Throws: interprocess_exception on error.
void lock();
- //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
+ //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
//!is already locked, returns true when success. The mutex must be unlocked
//!the same number of times it is locked.
//!Throws: interprocess_exception if a severe error is found
diff --git a/boost/interprocess/sync/interprocess_semaphore.hpp b/boost/interprocess/sync/interprocess_semaphore.hpp
index 4ffcdcf691..2a2f34fdcf 100644
--- a/boost/interprocess/sync/interprocess_semaphore.hpp
+++ b/boost/interprocess/sync/interprocess_semaphore.hpp
@@ -29,9 +29,9 @@
#include <boost/interprocess/sync/posix/semaphore.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/semaphore.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/semaphore.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/semaphore.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
@@ -45,7 +45,7 @@
namespace boost {
namespace interprocess {
-//!Wraps a interprocess_semaphore that can be placed in shared memory and can be
+//!Wraps a interprocess_semaphore that can be placed in shared memory and can be
//!shared between processes. Allows timed lock tries
class interprocess_semaphore
{
@@ -55,7 +55,7 @@ class interprocess_semaphore
interprocess_semaphore &operator=(const interprocess_semaphore &);
/// @endcond
public:
- //!Creates a interprocess_semaphore with the given initial count.
+ //!Creates a interprocess_semaphore with the given initial count.
//!interprocess_exception if there is an error.*/
interprocess_semaphore(unsigned int initialCount);
@@ -69,7 +69,7 @@ class interprocess_semaphore
void post();
//!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero,
- //!then the calling process/thread blocks until it can decrement the counter.
+ //!then the calling process/thread blocks until it can decrement the counter.
//!If there is an error an interprocess_exception exception is thrown.
void wait();
@@ -95,7 +95,7 @@ class interprocess_semaphore
#elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
#undef BOOST_INTERPROCESS_USE_WINDOWS
ipcdetail::windows_semaphore m_sem;
- #else
+ #else
#undef BOOST_INTERPROCESS_USE_POSIX
ipcdetail::posix_semaphore m_sem;
#endif //#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
diff --git a/boost/interprocess/sync/interprocess_upgradable_mutex.hpp b/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
index 048407f4b3..8d5a452626 100644
--- a/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
+++ b/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
@@ -30,7 +30,7 @@
namespace boost {
namespace interprocess {
-//!Wraps a interprocess_upgradable_mutex that can be placed in shared memory and can be
+//!Wraps a interprocess_upgradable_mutex that can be placed in shared memory and can be
//!shared between processes. Allows timed lock tries
class interprocess_upgradable_mutex
{
@@ -67,13 +67,13 @@ class interprocess_upgradable_mutex
//!Effects: The calling thread tries to acquire exclusive ownership of the mutex
//! waiting if necessary until no other thread has exclusive, sharable or
- //! upgradable ownership of the mutex or abs_time is reached.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! upgradable 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.
+ //!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();
@@ -87,21 +87,21 @@ class interprocess_upgradable_mutex
//!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.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire sharable ownership immediately returns true. If it
- //! has to wait, returns false.
+ //! 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.
+ //! 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.
+ //!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();
@@ -115,7 +115,7 @@ class interprocess_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! without waiting. If no other thread has exclusive or upgradable ownership
- //! of the mutex this succeeds.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire upgradable ownership immediately returns true.
//! If it has to wait, returns false.
//!Throws: interprocess_exception on error.
@@ -124,74 +124,74 @@ class interprocess_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! waiting if necessary until no other thread has exclusive or upgradable
//! ownership of the mutex or abs_time is reached.
- //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock_upgradable(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have upgradable ownership of the mutex.
- //!Effects: The calling thread releases the upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The calling thread releases the upgradable ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable();
//Demotions
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! upgradable ownership. This operation is non-blocking.
+ //! upgradable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_upgradable();
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_sharable();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock_sharable();
//Promotions
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
//! exclusive ownership. This operation will block until all threads with
- //! sharable ownership release their sharable lock.
+ //! sharable ownership release their sharable lock.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to
//! acquire exclusive ownership. This operation will fail if there are threads
- //! with sharable ownership, but it will maintain upgradable ownership.
+ //! with sharable ownership, but it will maintain upgradable ownership.
//!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to acquire
//! exclusive ownership, waiting if necessary until abs_time. This operation will
//! fail if there are threads with sharable ownership or timeout reaches, but it
- //! will maintain upgradable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! will maintain upgradable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error. */
bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Precondition: The thread must have sharable ownership of the mutex.
//!Effects: The thread atomically releases sharable ownership and tries to acquire
//! exclusive ownership. This operation will fail if there are threads with sharable
//! or upgradable ownership, but it will maintain sharable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!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.
+ //!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.
+ //! 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();
@@ -249,7 +249,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;
}
@@ -260,7 +260,7 @@ class interprocess_upgradable_mutex
template<int Dummy>
struct base_constants_t
{
- static const unsigned max_readers
+ static const unsigned max_readers
= ~(unsigned(3) << (sizeof(unsigned)*CHAR_BIT-2));
};
typedef base_constants_t<0> constants;
@@ -309,10 +309,10 @@ inline bool interprocess_upgradable_mutex::try_lock()
{
scoped_lock_t lock(m_mut, try_to_lock);
- //If we can't lock or any has there is any exclusive, upgradable
+ //If we can't lock or any has there is any exclusive, upgradable
//or sharable mark return false;
- if(!lock.owns()
- || this->m_ctrl.exclusive_in
+ if(!lock.owns()
+ || this->m_ctrl.exclusive_in
|| this->m_ctrl.num_upr_shar){
return false;
}
@@ -387,9 +387,9 @@ inline bool interprocess_upgradable_mutex::try_lock_upgradable()
//The upgradable lock must fail
//if an exclusive or upgradable lock has been acquired
//or there are too many sharable locks
- if(!lock.owns()
- || this->m_ctrl.exclusive_in
- || this->m_ctrl.upgradable_in
+ if(!lock.owns()
+ || this->m_ctrl.exclusive_in
+ || this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
return false;
}
@@ -414,11 +414,11 @@ inline bool interprocess_upgradable_mutex::timed_lock_upgradable
//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
+ 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
+ return!(this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar == constants::max_readers);
}
@@ -561,7 +561,7 @@ inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock()
//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;
@@ -584,7 +584,7 @@ inline bool interprocess_upgradable_mutex::try_unlock_upgradable_and_lock()
}
//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;
}
@@ -598,7 +598,7 @@ inline bool interprocess_upgradable_mutex::timed_unlock_upgradable_and_lock
//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;
@@ -618,10 +618,10 @@ inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock()
{
scoped_lock_t lock(m_mut, try_to_lock);
- //If we can't lock or any has there is any exclusive, upgradable
+ //If we can't lock or any has there is any exclusive, upgradable
//or sharable mark return false;
- if(!lock.owns()
- || this->m_ctrl.exclusive_in
+ if(!lock.owns()
+ || this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar != 1){
return false;
@@ -638,7 +638,7 @@ inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock_upgradab
//The upgradable lock must fail
//if an exclusive or upgradable lock has been acquired
if(!lock.owns()
- || this->m_ctrl.exclusive_in
+ || this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in){
return false;
}
diff --git a/boost/interprocess/sync/mutex_family.hpp b/boost/interprocess/sync/mutex_family.hpp
index a9215e24fe..b153ffea3e 100644
--- a/boost/interprocess/sync/mutex_family.hpp
+++ b/boost/interprocess/sync/mutex_family.hpp
@@ -29,7 +29,7 @@ namespace boost {
namespace interprocess {
-//!Describes interprocess_mutex family to use with Interprocess framework
+//!Describes interprocess_mutex family to use with Interprocess framework
//!based on boost::interprocess synchronization objects.
struct mutex_family
{
@@ -37,7 +37,7 @@ struct mutex_family
typedef boost::interprocess::interprocess_recursive_mutex recursive_mutex_type;
};
-//!Describes interprocess_mutex family to use with Interprocess frameworks
+//!Describes interprocess_mutex family to use with Interprocess frameworks
//!based on null operation synchronization objects.
struct null_mutex_family
{
diff --git a/boost/interprocess/sync/named_condition.hpp b/boost/interprocess/sync/named_condition.hpp
index c5529eda6c..ca0205ad73 100644
--- a/boost/interprocess/sync/named_condition.hpp
+++ b/boost/interprocess/sync/named_condition.hpp
@@ -22,7 +22,12 @@
#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/shm/named_condition.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
+#else
+ #include <boost/interprocess/sync/shm/named_condition.hpp>
+#endif
//!\file
//!Describes a named condition class for inter-process synchronization
@@ -50,7 +55,7 @@ class named_condition
//!If the condition can't be created throws interprocess_exception
named_condition(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global condition with a name.
+ //!Opens or creates a global condition with a name.
//!If the condition is created, this call is equivalent to
//!named_condition(create_only_t, ... )
//!If the condition is already created, this call is equivalent
@@ -71,7 +76,7 @@ class named_condition
//!use remove().
~named_condition();
- //!If there is a thread waiting on *this, change that
+ //!If there is a thread waiting on *this, change that
//!thread's state to ready. Otherwise there is no effect.*/
void notify_one();
@@ -79,8 +84,8 @@ class named_condition
//!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
+ //!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);
@@ -90,16 +95,16 @@ class named_condition
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,
+ //!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();
+ //!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);
@@ -110,7 +115,12 @@ class named_condition
/// @cond
private:
- ipcdetail::shm_named_condition m_cond;
+ #if defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ typedef ipcdetail::windows_named_condition condition_type;
+ #else
+ typedef ipcdetail::shm_named_condition condition_type;
+ #endif
+ condition_type m_cond;
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction()
@@ -160,7 +170,7 @@ inline bool named_condition::timed_wait
{ return m_cond.timed_wait(lock, abs_time, pred); }
inline bool named_condition::remove(const char *name)
-{ return ipcdetail::shm_named_condition::remove(name); }
+{ return condition_type::remove(name); }
/// @endcond
diff --git a/boost/interprocess/sync/named_mutex.hpp b/boost/interprocess/sync/named_mutex.hpp
index 3e56b81794..c34193c697 100644
--- a/boost/interprocess/sync/named_mutex.hpp
+++ b/boost/interprocess/sync/named_mutex.hpp
@@ -24,7 +24,11 @@
#include <boost/interprocess/permissions.hpp>
#if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
-#include <boost/interprocess/sync/posix/named_mutex.hpp>
+ #include <boost/interprocess/sync/posix/named_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#else
#include <boost/interprocess/sync/shm/named_mutex.hpp>
#endif
@@ -37,7 +41,7 @@ namespace interprocess {
class named_condition;
-//!A mutex with a global name, so it can be found from different
+//!A 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_mutex.
class named_mutex
@@ -56,7 +60,7 @@ class named_mutex
//!Throws interprocess_exception on error.
named_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global mutex with a name.
+ //!Opens or creates a global mutex with a name.
//!If the mutex is created, this call is equivalent to
//!named_mutex(create_only_t, ... )
//!If the mutex is already created, this call is equivalent
@@ -85,7 +89,7 @@ class named_mutex
//!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 interprocess_mutex, returns false when interprocess_mutex
//!is already locked, returns true when success.
//!Throws interprocess_exception if a severe error is found
bool try_lock();
@@ -104,15 +108,20 @@ class named_mutex
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
- #if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
- typedef ipcdetail::posix_named_mutex impl_t;
- impl_t m_mut;
+ #if defined(BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES)
+ typedef ipcdetail::posix_named_mutex impl_t;
+ impl_t m_mut;
+ #undef BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES
+ #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ typedef ipcdetail::windows_named_mutex impl_t;
+ impl_t m_mut;
+ #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 impl_t;
+ impl_t m_mut;
+ public:
+ interprocess_mutex *mutex() const
+ { return m_mut.mutex(); }
#endif
/// @endcond
diff --git a/boost/interprocess/sync/named_recursive_mutex.hpp b/boost/interprocess/sync/named_recursive_mutex.hpp
index 28768cea6f..2d4b9b2416 100644
--- a/boost/interprocess/sync/named_recursive_mutex.hpp
+++ b/boost/interprocess/sync/named_recursive_mutex.hpp
@@ -20,7 +20,12 @@
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/permissions.hpp>
-#include <boost/interprocess/sync/shm/named_recursive_mutex.hpp>
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_recursive_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
+#else
+ #include <boost/interprocess/sync/shm/named_recursive_mutex.hpp>
+#endif
//!\file
//!Describes a named named_recursive_mutex class for inter-process synchronization
@@ -32,7 +37,7 @@ namespace interprocess {
namespace ipcdetail{ class interprocess_tester; }
/// @endcond
-//!A recursive mutex with a global name, so it can be found from different
+//!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
@@ -49,7 +54,7 @@ class named_recursive_mutex
//!If the recursive_mutex can't be created throws interprocess_exception
named_recursive_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global recursive_mutex with a name.
+ //!Opens or creates a global recursive_mutex with a name.
//!If the recursive_mutex is created, this call is equivalent to
//!named_recursive_mutex(create_only_t, ... )
//!If the recursive_mutex is already created, this call is equivalent
@@ -78,7 +83,7 @@ class named_recursive_mutex
//!Throws interprocess_exception if a severe error is found.
void lock();
- //!Tries to lock the named_recursive_mutex, returns false when named_recursive_mutex
+ //!Tries to lock the named_recursive_mutex, returns false when named_recursive_mutex
//!is already locked, returns true when success.
//!Throws interprocess_exception if a severe error is found.
bool try_lock();
@@ -97,7 +102,12 @@ class named_recursive_mutex
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
- typedef ipcdetail::shm_named_recursive_mutex impl_t;
+ #if defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ typedef ipcdetail::windows_named_recursive_mutex impl_t;
+ #undef BOOST_INTERPROCESS_USE_WINDOWS
+ #else
+ typedef ipcdetail::shm_named_recursive_mutex impl_t;
+ #endif
impl_t m_mut;
/// @endcond
diff --git a/boost/interprocess/sync/named_semaphore.hpp b/boost/interprocess/sync/named_semaphore.hpp
index 33e06964f9..39c9096fb6 100644
--- a/boost/interprocess/sync/named_semaphore.hpp
+++ b/boost/interprocess/sync/named_semaphore.hpp
@@ -25,6 +25,10 @@
#if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES)
#include <boost/interprocess/sync/posix/named_semaphore.hpp>
+//Experimental...
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_semaphore.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#else
#include <boost/interprocess/sync/shm/named_semaphore.hpp>
#endif
@@ -35,8 +39,8 @@
namespace boost {
namespace interprocess {
-//!A semaphore with a global name, so it can be found from different
-//!processes. Allows several resource sharing patterns and efficient
+//!A semaphore with a global name, so it can be found from different
+//!processes. Allows several resource sharing patterns and efficient
//!acknowledgment mechanisms.
class named_semaphore
{
@@ -49,11 +53,11 @@ class named_semaphore
/// @endcond
public:
- //!Creates a global semaphore with a name, and an initial count.
+ //!Creates a global semaphore with a name, and an initial count.
//!If the semaphore can't be created throws interprocess_exception
named_semaphore(create_only_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
- //!Opens or creates a global semaphore with a name, and an initial count.
+ //!Opens or creates a global semaphore with a name, and an initial count.
//!If the semaphore is created, this call is equivalent to
//!named_semaphore(create_only_t, ...)
//!If the semaphore is already created, this call is equivalent to
@@ -80,7 +84,7 @@ class named_semaphore
void post();
//!Decrements the semaphore. If the semaphore value is not greater than zero,
- //!then the calling process/thread blocks until it can decrement the counter.
+ //!then the calling process/thread blocks until it can decrement the counter.
//!If there is an error an interprocess_exception exception is thrown.
void wait();
@@ -106,9 +110,12 @@ class named_semaphore
void dont_close_on_destruction();
#if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES)
- typedef ipcdetail::posix_named_semaphore impl_t;
+ typedef ipcdetail::posix_named_semaphore impl_t;
+ #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ #undef BOOST_INTERPROCESS_USE_WINDOWS
+ typedef ipcdetail::windows_named_semaphore impl_t;
#else
- typedef ipcdetail::shm_named_semaphore impl_t;
+ typedef ipcdetail::shm_named_semaphore impl_t;
#endif
impl_t m_sem;
/// @endcond
diff --git a/boost/interprocess/sync/named_upgradable_mutex.hpp b/boost/interprocess/sync/named_upgradable_mutex.hpp
index 61c6bb4086..c45fd08270 100644
--- a/boost/interprocess/sync/named_upgradable_mutex.hpp
+++ b/boost/interprocess/sync/named_upgradable_mutex.hpp
@@ -38,7 +38,7 @@ namespace ipcdetail{ class interprocess_tester; }
class named_condition;
-//!A upgradable mutex with a global name, so it can be found from different
+//!A upgradable 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 upgradable mutex.
class named_upgradable_mutex
@@ -52,11 +52,11 @@ class named_upgradable_mutex
/// @endcond
public:
- //!Creates a global upgradable mutex with a name.
+ //!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, and an initial count.
//!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
@@ -95,13 +95,13 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire exclusive ownership of the mutex
//! waiting if necessary until no other thread has exclusive, sharable or
- //! upgradable ownership of the mutex or abs_time is reached.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! upgradable 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.
+ //!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();
@@ -115,21 +115,21 @@ class named_upgradable_mutex
//!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.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire sharable ownership immediately returns true. If it
- //! has to wait, returns false.
+ //! 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.
+ //! 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.
+ //!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();
@@ -143,7 +143,7 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! without waiting. If no other thread has exclusive or upgradable ownership
- //! of the mutex this succeeds.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire upgradable ownership immediately returns true.
//! If it has to wait, returns false.
//!Throws: interprocess_exception on error.
@@ -152,66 +152,66 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! waiting if necessary until no other thread has exclusive or upgradable
//! ownership of the mutex or abs_time is reached.
- //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock_upgradable(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have upgradable ownership of the mutex.
- //!Effects: The calling thread releases the upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The calling thread releases the upgradable ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable();
//Demotions
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! upgradable ownership. This operation is non-blocking.
+ //! upgradable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_upgradable();
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_sharable();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock_sharable();
//Promotions
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
//! exclusive ownership. This operation will block until all threads with
- //! sharable ownership release it.
+ //! sharable ownership release it.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to
//! acquire exclusive ownership. This operation will fail if there are threads
- //! with sharable ownership, but it will maintain upgradable ownership.
+ //! with sharable ownership, but it will maintain upgradable ownership.
//!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to acquire
//! exclusive ownership, waiting if necessary until abs_time. This operation will
//! fail if there are threads with sharable ownership or timeout reaches, but it
- //! will maintain upgradable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! will maintain upgradable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Precondition: The thread must have sharable ownership of the mutex.
//!Effects: The thread atomically releases sharable ownership and tries to acquire
//! exclusive ownership. This operation will fail if there are threads with sharable
//! or upgradable ownership, but it will maintain sharable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock();
diff --git a/boost/interprocess/sync/posix/condition.hpp b/boost/interprocess/sync/posix/condition.hpp
index 213e4ce8b5..48be099f60 100644
--- a/boost/interprocess/sync/posix/condition.hpp
+++ b/boost/interprocess/sync/posix/condition.hpp
@@ -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>
@@ -44,7 +44,7 @@ class posix_condition
//!liberating system resources.
~posix_condition();
- //!If there is a thread waiting on *this, change that
+ //!If there is a thread waiting on *this, change that
//!thread's state to ready. Otherwise there is no effect.
void notify_one();
@@ -52,8 +52,8 @@ class posix_condition
//!If there are no waiting threads, notify_all() has no effect.
void notify_all();
- //!Releases the lock on the posix_mutex object associated with lock, blocks
- //!the current thread of execution until readied by a call to
+ //!Releases the lock on the posix_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)
@@ -75,9 +75,9 @@ class posix_condition
this->do_wait(*lock.mutex());
}
- //!Releases the lock on the posix_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,
+ //!Releases the lock on the posix_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>
@@ -92,8 +92,8 @@ class posix_condition
return this->do_timed_wait(abs_time, *lock.mutex());
}
- //!The same as: while (!pred()) {
- //! if (!timed_wait(lock, abs_time)) return pred();
+ //!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)
diff --git a/boost/interprocess/sync/posix/mutex.hpp b/boost/interprocess/sync/posix/mutex.hpp
index 22e2ec04b9..393807c97a 100644
--- a/boost/interprocess/sync/posix/mutex.hpp
+++ b/boost/interprocess/sync/posix/mutex.hpp
@@ -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>
@@ -80,7 +80,7 @@ inline posix_mutex::posix_mutex()
mut.release();
}
-inline posix_mutex::~posix_mutex()
+inline posix_mutex::~posix_mutex()
{
int res = pthread_mutex_destroy(&m_mut);
BOOST_ASSERT(res == 0);(void)res;
@@ -88,7 +88,7 @@ inline posix_mutex::~posix_mutex()
inline void posix_mutex::lock()
{
- if (pthread_mutex_lock(&m_mut) != 0)
+ if (pthread_mutex_lock(&m_mut) != 0)
throw lock_exception();
}
diff --git a/boost/interprocess/sync/posix/pthread_helpers.hpp b/boost/interprocess/sync/posix/pthread_helpers.hpp
index c09ce200cf..bcbc44be33 100644
--- a/boost/interprocess/sync/posix/pthread_helpers.hpp
+++ b/boost/interprocess/sync/posix/pthread_helpers.hpp
@@ -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 {
@@ -29,7 +29,7 @@ namespace ipcdetail{
#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
//!Makes pthread_mutexattr_t cleanup easy when using exceptions
- struct mutexattr_wrapper
+ struct mutexattr_wrapper
{
//!Constructor
mutexattr_wrapper(bool recursive = false)
@@ -51,7 +51,7 @@ namespace ipcdetail{
};
//!Makes pthread_condattr_t cleanup easy when using exceptions
- struct condattr_wrapper
+ struct condattr_wrapper
{
//!Constructor
condattr_wrapper()
@@ -86,7 +86,7 @@ namespace ipcdetail{
void release() {mp_mut = 0; }
- private:
+ private:
pthread_mutex_t *mp_mut;
};
@@ -94,7 +94,7 @@ namespace ipcdetail{
class condition_initializer
{
public:
- condition_initializer(pthread_cond_t &cond, pthread_condattr_t &cond_attr)
+ condition_initializer(pthread_cond_t &cond, pthread_condattr_t &cond_attr)
: mp_cond(&cond)
{
if(pthread_cond_init(mp_cond, &cond_attr)!= 0)
@@ -105,7 +105,7 @@ namespace ipcdetail{
void release() { mp_cond = 0; }
- private:
+ private:
pthread_cond_t *mp_cond;
};
@@ -114,7 +114,7 @@ namespace ipcdetail{
#if defined(BOOST_INTERPROCESS_POSIX_BARRIERS) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
//!Makes pthread_barrierattr_t cleanup easy when using exceptions
- struct barrierattr_wrapper
+ struct barrierattr_wrapper
{
//!Constructor
barrierattr_wrapper()
@@ -138,8 +138,8 @@ namespace ipcdetail{
{
public:
//!Constructor. Takes barrier attributes to initialize the barrier
- barrier_initializer(pthread_barrier_t &mut,
- pthread_barrierattr_t &mut_attr,
+ barrier_initializer(pthread_barrier_t &mut,
+ pthread_barrierattr_t &mut_attr,
int count)
: mp_barrier(&mut)
{
@@ -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/recursive_mutex.hpp b/boost/interprocess/sync/posix/recursive_mutex.hpp
index baa670fa9a..456c9a4874 100644
--- a/boost/interprocess/sync/posix/recursive_mutex.hpp
+++ b/boost/interprocess/sync/posix/recursive_mutex.hpp
@@ -31,7 +31,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>
@@ -78,7 +78,7 @@ inline posix_recursive_mutex::~posix_recursive_mutex()
inline void posix_recursive_mutex::lock()
{
- if (pthread_mutex_lock(&m_mut) != 0)
+ if (pthread_mutex_lock(&m_mut) != 0)
throw lock_exception();
}
diff --git a/boost/interprocess/sync/posix/semaphore_wrapper.hpp b/boost/interprocess/sync/posix/semaphore_wrapper.hpp
index 1aeef47662..22184cda9d 100644
--- a/boost/interprocess/sync/posix/semaphore_wrapper.hpp
+++ b/boost/interprocess/sync/posix/semaphore_wrapper.hpp
@@ -18,7 +18,7 @@
#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
#include <boost/interprocess/permissions.hpp>
-#include <fcntl.h> //O_CREAT, O_*...
+#include <fcntl.h> //O_CREAT, O_*...
#include <unistd.h> //close
#include <string> //std::string
#include <semaphore.h> //sem_* family, SEM_VALUE_MAX
@@ -42,7 +42,7 @@ namespace interprocess {
namespace ipcdetail {
inline bool semaphore_open
- (sem_t *&handle, create_enum_t type, const char *origname,
+ (sem_t *&handle, create_enum_t type, const char *origname,
unsigned int count = 0, const permissions &perm = permissions())
{
std::string name;
@@ -103,7 +103,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);
}
}
@@ -138,7 +138,7 @@ inline void semaphore_init(sem_t *handle, unsigned int initialCount)
inline void semaphore_destroy(sem_t *handle)
{
int ret = sem_destroy(handle);
- if(ret != 0){
+ if(ret != 0){
BOOST_ASSERT(0);
}
}
diff --git a/boost/interprocess/sync/scoped_lock.hpp b/boost/interprocess/sync/scoped_lock.hpp
index bfef63a30a..61fe93e5b3 100644
--- a/boost/interprocess/sync/scoped_lock.hpp
+++ b/boost/interprocess/sync/scoped_lock.hpp
@@ -89,7 +89,7 @@ class scoped_lock
: mp_mutex(&m), m_locked(true)
{}
- //!Effects: m.try_lock().
+ //!Effects: m.try_lock().
//!Postconditions: mutex() == &m. owns() == the return value of the
//! m.try_lock() executed within the constructor.
//!Notes: The constructor will take ownership of the mutex if it can do
@@ -101,7 +101,7 @@ class scoped_lock
: mp_mutex(&m), m_locked(mp_mutex->try_lock())
{}
- //!Effects: m.timed_lock(abs_time).
+ //!Effects: m.timed_lock(abs_time).
//!Postconditions: mutex() == &m. owns() == the return value of the
//! m.timed_lock(abs_time) executed within the constructor.
//!Notes: The constructor will take ownership of the mutex if it can do
@@ -128,7 +128,7 @@ class scoped_lock
{ mp_mutex = scop.release(); }
//!Effects: If upgr.owns() then calls unlock_upgradable_and_lock() on the
- //! referenced mutex. upgr.release() is called.
+ //! referenced mutex. upgr.release() is called.
//!Postconditions: mutex() == the value upgr.mutex() had before the construction.
//! upgr.mutex() == 0. owns() == upgr.owns() before the construction.
//! upgr.owns() == false after the construction.
@@ -155,12 +155,12 @@ class scoped_lock
//!Effects: If upgr.owns() then calls try_unlock_upgradable_and_lock() on the
//!referenced mutex:
//! a)if try_unlock_upgradable_and_lock() returns true then mutex() obtains
- //! the value from upgr.release() and owns() is set to true.
+ //! 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
- //! a default construction.
+ //! 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
+ //! and owns() is set to false
//!Notes: This construction will not block. It will try to obtain mutex
//! ownership from upgr immediately, while changing the lock type from a
//! "read lock" to a "write lock". If the "read lock" isn't held in the
@@ -186,12 +186,12 @@ class scoped_lock
//!Effects: If upgr.owns() then calls timed_unlock_upgradable_and_lock(abs_time)
//! on the referenced mutex:
//! a)if timed_unlock_upgradable_and_lock(abs_time) returns true then mutex()
- //! obtains the value from upgr.release() and owns() is set to true.
+ //! obtains the value from upgr.release() and owns() is set to true.
//! b)if timed_unlock_upgradable_and_lock(abs_time) returns false then upgr
//! is 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
+ //! and owns() is set to false
//!Notes: This construction will not block. It will try to obtain mutex ownership
//! from upgr immediately, while changing the lock type from a "read lock" to a
//! "write lock". If the "read lock" isn't held in the first place, the mutex
@@ -214,14 +214,14 @@ class scoped_lock
}
//!Effects: If shar.owns() then calls try_unlock_sharable_and_lock() on the
- //!referenced mutex.
+ //!referenced mutex.
//! a)if try_unlock_sharable_and_lock() returns true then mutex() obtains
- //! the value from shar.release() and owns() is set to true.
+ //! the value from shar.release() and owns() is set to true.
//! b)if try_unlock_sharable_and_lock() returns false then shar is
//! unaffected and this scoped_lock construction has the same
- //! effects as a default construction.
+ //! effects as a default construction.
//! c)Else shar.owns() is false. mutex() obtains the value from
- //! shar.release() and owns() is set to false
+ //! shar.release() and owns() is set to false
//!Notes: This construction will not block. It will try to obtain mutex
//! ownership from shar immediately, while changing the lock type from a
//! "read lock" to a "write lock". If the "read lock" isn't held in the
@@ -253,13 +253,13 @@ class scoped_lock
}
//!Effects: If owns() before the call, then unlock() is called on mutex().
- //! *this gets the state of scop and scop gets set to a default constructed state.
+ //! *this gets the state of scop and scop gets set to a default constructed state.
//!Notes: With a recursive mutex it is possible that both this and scop own
//! the same mutex before the assignment. In this case, this will own the
//! 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();
@@ -281,7 +281,7 @@ class scoped_lock
}
//!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
- //! exception. Calls try_lock() on the referenced mutex.
+ //! exception. Calls try_lock() on the referenced mutex.
//!Postconditions: owns() == the value returned from mutex()->try_lock().
//!Notes: The scoped_lock changes from a state of not owning the mutex, to
//! owning the mutex, but only if blocking was not required. If the
@@ -348,8 +348,8 @@ class scoped_lock
m_locked = false;
return mut;
}
-
- //!Effects: Swaps state with moved lock.
+
+ //!Effects: Swaps state with moved lock.
//!Throws: Nothing.
void swap( scoped_lock<mutex_type> &other)
{
@@ -359,7 +359,7 @@ class scoped_lock
/// @cond
private:
- mutex_type *mp_mutex;
+ mutex_type *mp_mutex;
bool m_locked;
/// @endcond
};
diff --git a/boost/interprocess/sync/sharable_lock.hpp b/boost/interprocess/sync/sharable_lock.hpp
index c8b7c1d26e..9342e45a46 100644
--- a/boost/interprocess/sync/sharable_lock.hpp
+++ b/boost/interprocess/sync/sharable_lock.hpp
@@ -67,7 +67,7 @@ class sharable_lock
{}
//!Effects: m.lock_sharable().
- //!Postconditions: owns() == true and mutex() == &m.
+ //!Postconditions: owns() == true and mutex() == &m.
//!Notes: The constructor will take sharable-ownership of the mutex. If
//! another thread already owns the mutex with exclusive ownership
//! (scoped_lock), this thread will block until the mutex is released.
@@ -104,7 +104,7 @@ class sharable_lock
: mp_mutex(&m), m_locked(false)
{ m_locked = mp_mutex->try_lock_sharable(); }
- //!Effects: m.timed_lock_sharable(abs_time)
+ //!Effects: m.timed_lock_sharable(abs_time)
//!Postconditions: mutex() == &m. owns() == the return value of the
//! m.timed_lock_sharable() executed within the constructor.
//!Notes: The constructor will take sharable-ownership of the mutex if it
@@ -132,7 +132,7 @@ class sharable_lock
//! referenced mutex.
//!Postconditions: mutex() == the value upgr.mutex() had before the construction.
//! upgr.mutex() == 0 owns() == the value of upgr.owns() before construction.
- //! upgr.owns() == false after the construction.
+ //! upgr.owns() == false after the construction.
//!Notes: If upgr is locked, this constructor will lock this sharable_lock while
//! unlocking upgr. Only a moved sharable_lock's will match this
//! signature. An non-moved upgradable_lock can be moved with the expression:
@@ -156,7 +156,7 @@ class sharable_lock
//! scop.mutex() == 0 owns() == scop.owns() before the constructor. After the
//! construction, scop.owns() == false.
//!Notes: If scop is locked, this constructor will transfer the exclusive ownership
- //! to a sharable-ownership of this sharable_lock.
+ //! to a sharable-ownership of this sharable_lock.
//! Only a moved scoped_lock's will match this
//! signature. An non-moved scoped_lock can be moved with the expression:
//! "boost::move(lock);".
@@ -184,12 +184,12 @@ class sharable_lock
}
//!Effects: If owns() before the call, then unlock_sharable() is called on mutex().
- //! *this gets the state of upgr and upgr gets set to a default constructed state.
+ //! *this gets the state of upgr and upgr gets set to a default constructed state.
//!Notes: With a recursive mutex it is possible that both this and upgr own the mutex
//! 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);
@@ -282,7 +282,7 @@ class sharable_lock
return mut;
}
- //!Effects: Swaps state with moved lock.
+ //!Effects: Swaps state with moved lock.
//!Throws: Nothing.
void swap(sharable_lock<mutex_type> &other)
{
diff --git a/boost/interprocess/sync/shm/named_condition.hpp b/boost/interprocess/sync/shm/named_condition.hpp
index 0d67c25757..9d7cd77e11 100644
--- a/boost/interprocess/sync/shm/named_condition.hpp
+++ b/boost/interprocess/sync/shm/named_condition.hpp
@@ -28,7 +28,7 @@
#include <boost/interprocess/sync/shm/named_creation_functor.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/permissions.hpp>
-#if defined BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
+#if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#endif
@@ -42,7 +42,7 @@ namespace interprocess {
namespace ipcdetail {
/// @cond
-namespace ipcdetail{ class interprocess_tester; }
+class interprocess_tester;
/// @endcond
//! A global condition variable that can be created by name.
@@ -61,7 +61,7 @@ class shm_named_condition
//!If the condition can't be created throws interprocess_exception
shm_named_condition(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global condition with a name.
+ //!Opens or creates a global condition with a name.
//!If the condition is created, this call is equivalent to
//!shm_named_condition(create_only_t, ... )
//!If the condition is already created, this call is equivalent
@@ -82,7 +82,7 @@ class shm_named_condition
//!use remove().
~shm_named_condition();
- //!If there is a thread waiting on *this, change that
+ //!If there is a thread waiting on *this, change that
//!thread's state to ready. Otherwise there is no effect.*/
void notify_one();
@@ -90,8 +90,8 @@ class shm_named_condition
//!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
+ //!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);
@@ -101,16 +101,16 @@ class shm_named_condition
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,
+ //!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();
+ //!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);
@@ -147,6 +147,9 @@ class shm_named_condition
void unlock() { l_.lock(); }
};
+ //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_; }
@@ -156,7 +159,7 @@ class shm_named_condition
{
//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);
@@ -173,18 +176,18 @@ class shm_named_condition
{
//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);
+ //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);
+ 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);
+ //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
+ #else //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
template<class Lock>
class lock_wrapper
{
@@ -210,7 +213,7 @@ class shm_named_condition
private:
Lock &l_;
};
- #endif
+ #endif //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
friend class boost::interprocess::ipcdetail::interprocess_tester;
void dont_close_on_destruction();
diff --git a/boost/interprocess/sync/shm/named_creation_functor.hpp b/boost/interprocess/sync/shm/named_creation_functor.hpp
index 11a1db1d6f..9d752c837a 100644
--- a/boost/interprocess/sync/shm/named_creation_functor.hpp
+++ b/boost/interprocess/sync/shm/named_creation_functor.hpp
@@ -38,7 +38,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;
diff --git a/boost/interprocess/sync/shm/named_mutex.hpp b/boost/interprocess/sync/shm/named_mutex.hpp
index a71eb4fe68..f32fa70044 100644
--- a/boost/interprocess/sync/shm/named_mutex.hpp
+++ b/boost/interprocess/sync/shm/named_mutex.hpp
@@ -37,7 +37,7 @@ namespace ipcdetail {
class named_condition;
-//!A mutex with a global name, so it can be found from different
+//!A 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 mutex.
class shm_named_mutex
@@ -56,7 +56,7 @@ class shm_named_mutex
//!Throws interprocess_exception on error.
shm_named_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global mutex with a name.
+ //!Opens or creates a global mutex with a name.
//!If the mutex is created, this call is equivalent to
//!shm_named_mutex(create_only_t, ... )
//!If the mutex is already created, this call is equivalent
@@ -85,7 +85,7 @@ class shm_named_mutex
//!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 interprocess_mutex, returns false when interprocess_mutex
//!is already locked, returns true when success.
//!Throws interprocess_exception if a severe error is found
bool try_lock();
diff --git a/boost/interprocess/sync/shm/named_recursive_mutex.hpp b/boost/interprocess/sync/shm/named_recursive_mutex.hpp
index 461c97eb32..7235571254 100644
--- a/boost/interprocess/sync/shm/named_recursive_mutex.hpp
+++ b/boost/interprocess/sync/shm/named_recursive_mutex.hpp
@@ -51,7 +51,7 @@ class shm_named_recursive_mutex
//!If the recursive_mutex can't be created throws interprocess_exception
shm_named_recursive_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global recursive_mutex with a name.
+ //!Opens or creates a global recursive_mutex with a name.
//!If the recursive_mutex is created, this call is equivalent to
//!shm_named_recursive_mutex(create_only_t, ... )
//!If the recursive_mutex is already created, this call is equivalent
@@ -80,7 +80,7 @@ class shm_named_recursive_mutex
//!Throws interprocess_exception if a severe error is found.
void lock();
- //!Tries to lock the shm_named_recursive_mutex, returns false when shm_named_recursive_mutex
+ //!Tries to lock the shm_named_recursive_mutex, returns false when shm_named_recursive_mutex
//!is already locked, returns true when success.
//!Throws interprocess_exception if a severe error is found.
bool try_lock();
diff --git a/boost/interprocess/sync/shm/named_upgradable_mutex.hpp b/boost/interprocess/sync/shm/named_upgradable_mutex.hpp
index 338fa98f7d..0975a6ed2b 100644
--- a/boost/interprocess/sync/shm/named_upgradable_mutex.hpp
+++ b/boost/interprocess/sync/shm/named_upgradable_mutex.hpp
@@ -38,7 +38,7 @@ namespace ipcdetail{ class interprocess_tester; }
class named_condition;
-//!A upgradable mutex with a global name, so it can be found from different
+//!A upgradable 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 upgradable mutex.
class named_upgradable_mutex
@@ -52,11 +52,11 @@ class named_upgradable_mutex
/// @endcond
public:
- //!Creates a global upgradable mutex with a name.
+ //!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, and an initial count.
//!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
@@ -95,13 +95,13 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire exclusive ownership of the mutex
//! waiting if necessary until no other thread has exclusive, sharable or
- //! upgradable ownership of the mutex or abs_time is reached.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! upgradable 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.
+ //!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();
@@ -115,21 +115,21 @@ class named_upgradable_mutex
//!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.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire sharable ownership immediately returns true. If it
- //! has to wait, returns false.
+ //! 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.
+ //! 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.
+ //!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();
@@ -143,7 +143,7 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! without waiting. If no other thread has exclusive or upgradable ownership
- //! of the mutex this succeeds.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire upgradable ownership immediately returns true.
//! If it has to wait, returns false.
//!Throws: interprocess_exception on error.
@@ -152,66 +152,66 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! waiting if necessary until no other thread has exclusive or upgradable
//! ownership of the mutex or abs_time is reached.
- //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock_upgradable(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have upgradable ownership of the mutex.
- //!Effects: The calling thread releases the upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The calling thread releases the upgradable ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable();
//Demotions
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! upgradable ownership. This operation is non-blocking.
+ //! upgradable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_upgradable();
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_sharable();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock_sharable();
//Promotions
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
//! exclusive ownership. This operation will block until all threads with
- //! sharable ownership release it.
+ //! sharable ownership release it.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to
//! acquire exclusive ownership. This operation will fail if there are threads
- //! with sharable ownership, but it will maintain upgradable ownership.
+ //! with sharable ownership, but it will maintain upgradable ownership.
//!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to acquire
//! exclusive ownership, waiting if necessary until abs_time. This operation will
//! fail if there are threads with sharable ownership or timeout reaches, but it
- //! will maintain upgradable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! will maintain upgradable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Precondition: The thread must have sharable ownership of the mutex.
//!Effects: The thread atomically releases sharable ownership and tries to acquire
//! exclusive ownership. This operation will fail if there are threads with sharable
//! or upgradable ownership, but it will maintain sharable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock();
diff --git a/boost/interprocess/sync/spin/condition.hpp b/boost/interprocess/sync/spin/condition.hpp
index 5a37d9be2d..55dd79b406 100644
--- a/boost/interprocess/sync/spin/condition.hpp
+++ b/boost/interprocess/sync/spin/condition.hpp
@@ -110,7 +110,7 @@ inline spin_condition::spin_condition()
}
inline spin_condition::~spin_condition()
-{
+{
//Trivial destructor
}
@@ -126,15 +126,15 @@ inline void spin_condition::notify_all()
inline void spin_condition::notify(boost::uint32_t command)
{
- //This mutex guarantees that no other thread can enter to the
+ //This mutex guarantees that no other thread can enter to the
//do_timed_wait method logic, so that thread count will be
//constant until the function writes a NOTIFY_ALL command.
- //It also guarantees that no other notification can be signaled
+ //It also guarantees that no other notification can be signaled
//on this spin_condition before this one ends
m_enter_mut.lock();
//Return if there are no waiters
- if(!atomic_read32(&m_num_waiters)) {
+ if(!atomic_read32(&m_num_waiters)) {
m_enter_mut.unlock();
return;
}
@@ -167,18 +167,18 @@ inline bool spin_condition::do_timed_wait
template<class InterprocessMutex>
inline bool spin_condition::do_timed_wait(bool tout_enabled,
- const boost::posix_time::ptime &abs_time,
+ const boost::posix_time::ptime &abs_time,
InterprocessMutex &mut)
{
boost::posix_time::ptime now = microsec_clock::universal_time();
-
+
if(tout_enabled){
if(now >= abs_time) return false;
}
typedef boost::interprocess::scoped_lock<spin_mutex> InternalLock;
- //The enter mutex guarantees that while executing a notification,
- //no other thread can execute the do_timed_wait method.
+ //The enter mutex guarantees that while executing a notification,
+ //no other thread can execute the do_timed_wait method.
{
//---------------------------------------------------------------
InternalLock lock;
@@ -205,8 +205,8 @@ 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
+
+ //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
@@ -229,8 +229,8 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
//There is an ongoing notification, we will try again later
continue;
}
- //No notification in execution, since enter mutex is locked.
- //We will execute time-out logic, so we will decrement count,
+ //No notification in execution, since enter mutex is locked.
+ //We will execute time-out logic, so we will decrement count,
//release the enter mutex and return false.
break;
}
@@ -253,7 +253,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.
@@ -262,8 +262,8 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
break;
}
else{
- //If it is a NOTIFY_ALL command, all threads should return
- //from do_timed_wait function. Decrement wait count.
+ //If it is a NOTIFY_ALL command, all threads should return
+ //from do_timed_wait function. Decrement wait count.
unlock_enter_mut = 1 == atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
//Check if this is the last thread of notify_all waiters
//Only the last thread will release the mutex
@@ -275,7 +275,7 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
}
}
- //Unlock the enter mutex if it is a single notification, if this is
+ //Unlock the enter mutex if it is a single notification, if this is
//the last notified thread in a notify_all or a timeout has occurred
if(unlock_enter_mut){
m_enter_mut.unlock();
diff --git a/boost/interprocess/sync/spin/mutex.hpp b/boost/interprocess/sync/spin/mutex.hpp
index ef0b47d95a..926f7237c0 100644
--- a/boost/interprocess/sync/spin/mutex.hpp
+++ b/boost/interprocess/sync/spin/mutex.hpp
@@ -45,15 +45,15 @@ class spin_mutex
volatile boost::uint32_t m_s;
};
-inline spin_mutex::spin_mutex()
- : m_s(0)
+inline spin_mutex::spin_mutex()
+ : m_s(0)
{
//Note that this class is initialized to zero.
//So zeroed memory can be interpreted as an
//initialized mutex
}
-inline spin_mutex::~spin_mutex()
+inline spin_mutex::~spin_mutex()
{
//Trivial destructor
}
@@ -73,7 +73,7 @@ inline void spin_mutex::lock(void)
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;
}
diff --git a/boost/interprocess/sync/spin/recursive_mutex.hpp b/boost/interprocess/sync/spin/recursive_mutex.hpp
index 05ad65eac0..a763f9c72d 100644
--- a/boost/interprocess/sync/spin/recursive_mutex.hpp
+++ b/boost/interprocess/sync/spin/recursive_mutex.hpp
@@ -68,7 +68,7 @@ class spin_recursive_mutex
volatile boost::uint32_t m_s;
};
-inline spin_recursive_mutex::spin_recursive_mutex()
+inline spin_recursive_mutex::spin_recursive_mutex()
: m_nLockCount(0), m_nOwner(ipcdetail::get_invalid_systemwide_thread_id()){}
inline spin_recursive_mutex::~spin_recursive_mutex(){}
@@ -83,7 +83,7 @@ inline void spin_recursive_mutex::lock()
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
- }
+ }
++m_nLockCount;
}
else{
@@ -103,7 +103,7 @@ inline bool spin_recursive_mutex::try_lock()
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
- }
+ }
++m_nLockCount;
return true;
}
@@ -129,7 +129,7 @@ inline bool spin_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
- }
+ }
++m_nLockCount;
return true;
}
diff --git a/boost/interprocess/sync/upgradable_lock.hpp b/boost/interprocess/sync/upgradable_lock.hpp
index 93c2ed6bc4..fb86374ca1 100644
--- a/boost/interprocess/sync/upgradable_lock.hpp
+++ b/boost/interprocess/sync/upgradable_lock.hpp
@@ -85,7 +85,7 @@ class upgradable_lock
: mp_mutex(&m), m_locked(true)
{}
- //!Effects: m.try_lock_upgradable().
+ //!Effects: m.try_lock_upgradable().
//!Postconditions: mutex() == &m. owns() == the return value of the
//! m.try_lock_upgradable() executed within the constructor.
//!Notes: The constructor will take upgradable-ownership of the mutex
@@ -97,7 +97,7 @@ class upgradable_lock
: mp_mutex(&m), m_locked(false)
{ m_locked = mp_mutex->try_lock_upgradable(); }
- //!Effects: m.timed_lock_upgradable(abs_time)
+ //!Effects: m.timed_lock_upgradable(abs_time)
//!Postconditions: mutex() == &m. owns() == the return value of the
//! m.timed_lock_upgradable() executed within the constructor.
//!Notes: The constructor will take upgradable-ownership of the mutex if it
@@ -123,7 +123,7 @@ class upgradable_lock
: mp_mutex(0), m_locked(upgr.owns())
{ mp_mutex = upgr.release(); }
- //!Effects: If scop.owns(), m_.unlock_and_lock_upgradable().
+ //!Effects: If scop.owns(), m_.unlock_and_lock_upgradable().
//!Postconditions: mutex() == the value scop.mutex() had before the construction.
//! scop.mutex() == 0. owns() == scop.owns() before the constructor. After the
//! construction, scop.owns() == false.
@@ -146,12 +146,12 @@ class upgradable_lock
}
//!Effects: If shar.owns() then calls try_unlock_sharable_and_lock_upgradable()
- //! on the referenced mutex.
+ //! on the referenced mutex.
//! a)if try_unlock_sharable_and_lock_upgradable() returns true then mutex()
- //! obtains the value from shar.release() and owns() is set to true.
+ //! obtains the value from shar.release() and owns() is set to true.
//! b)if try_unlock_sharable_and_lock_upgradable() returns false then shar is
//! unaffected and this upgradable_lock construction has the same
- //! effects as a default construction.
+ //! effects as a default construction.
//! c)Else shar.owns() is false. mutex() obtains the value from shar.release()
//! and owns() is set to false.
//!Notes: This construction will not block. It will try to obtain mutex
@@ -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);
@@ -286,7 +286,7 @@ class upgradable_lock
return mut;
}
- //!Effects: Swaps state with moved lock.
+ //!Effects: Swaps state with moved lock.
//!Throws: Nothing.
void swap(upgradable_lock<mutex_type> &other)
{
diff --git a/boost/interprocess/sync/windows/condition.hpp b/boost/interprocess/sync/windows/condition.hpp
index 167b8730c3..9695c21044 100644
--- a/boost/interprocess/sync/windows/condition.hpp
+++ b/boost/interprocess/sync/windows/condition.hpp
@@ -20,133 +20,8 @@
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/windows/semaphore.hpp>
#include <boost/interprocess/sync/windows/mutex.hpp>
-#include <boost/cstdint.hpp>
-#include <limits>
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//
-// Condition variable algorithm taken from pthreads-win32 discussion.
-//
-// The algorithm was developed by Alexander Terekhov in colaboration with
-// Louis Thomas.
-//
-// Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
-//
-// semBlockLock - bin.semaphore
-// semBlockQueue - semaphore
-// mtxExternal - mutex or CS
-// mtxUnblockLock - mutex or CS
-// nWaitersGone - int
-// nWaitersBlocked - int
-// nWaitersToUnblock - int
-//
-// wait( timeout ) {
-//
-// [auto: register int result ] // error checking omitted
-// [auto: register int nSignalsWasLeft ]
-// [auto: register int nWaitersWasGone ]
-//
-// sem_wait( semBlockLock );
-// nWaitersBlocked++;
-// sem_post( semBlockLock );
-//
-// unlock( mtxExternal );
-// bTimedOut = sem_wait( semBlockQueue,timeout );
-//
-// lock( mtxUnblockLock );
-// if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
-// if ( bTimedOut ) { // timeout (or canceled)
-// if ( 0 != nWaitersBlocked ) {
-// nWaitersBlocked--;
-// }
-// else {
-// nWaitersGone++; // count spurious wakeups.
-// }
-// }
-// if ( 0 == --nWaitersToUnblock ) {
-// if ( 0 != nWaitersBlocked ) {
-// sem_post( semBlockLock ); // open the gate.
-// nSignalsWasLeft = 0; // do not open the gate
-// // below again.
-// }
-// else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
-// nWaitersGone = 0;
-// }
-// }
-// }
-// else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
-// // spurious semaphore :-)
-// sem_wait( semBlockLock );
-// nWaitersBlocked -= nWaitersGone; // something is going on here
-// // - test of timeouts? :-)
-// sem_post( semBlockLock );
-// nWaitersGone = 0;
-// }
-// unlock( mtxUnblockLock );
-//
-// if ( 1 == nSignalsWasLeft ) {
-// if ( 0 != nWaitersWasGone ) {
-// // sem_adjust( semBlockQueue,-nWaitersWasGone );
-// while ( nWaitersWasGone-- ) {
-// sem_wait( semBlockQueue ); // better now than spurious later
-// }
-// } sem_post( semBlockLock ); // open the gate
-// }
-//
-// lock( mtxExternal );
-//
-// return ( bTimedOut ) ? ETIMEOUT : 0;
-// }
-//
-// signal(bAll) {
-//
-// [auto: register int result ]
-// [auto: register int nSignalsToIssue]
-//
-// lock( mtxUnblockLock );
-//
-// if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
-// if ( 0 == nWaitersBlocked ) { // NO-OP
-// return unlock( mtxUnblockLock );
-// }
-// if (bAll) {
-// nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
-// nWaitersBlocked = 0;
-// }
-// else {
-// nSignalsToIssue = 1;
-// nWaitersToUnblock++;
-// nWaitersBlocked--;
-// }
-// }
-// else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
-// sem_wait( semBlockLock ); // close the gate
-// if ( 0 != nWaitersGone ) {
-// nWaitersBlocked -= nWaitersGone;
-// nWaitersGone = 0;
-// }
-// if (bAll) {
-// nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
-// nWaitersBlocked = 0;
-// }
-// else {
-// nSignalsToIssue = nWaitersToUnblock = 1;
-// nWaitersBlocked--;
-// }
-// }
-// else { // NO-OP
-// return unlock( mtxUnblockLock );
-// }
-//
-// unlock( mtxUnblockLock );
-// sem_post( semBlockQueue,nSignalsToIssue );
-// return result;
-// }
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
+
namespace boost {
namespace interprocess {
@@ -156,6 +31,7 @@ class windows_condition
{
windows_condition(const windows_condition &);
windows_condition &operator=(const windows_condition &);
+
public:
windows_condition();
~windows_condition();
@@ -217,162 +93,71 @@ class windows_condition
private:
- template<class InterprocessMutex>
- bool do_timed_wait(bool timeout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mut);
- void do_signal (bool broadcast);
-
- boost::int32_t m_nwaiters_blocked;
- boost::int32_t m_nwaiters_gone;
- boost::int32_t m_nwaiters_to_unblock;
- windows_semaphore m_sem_block_queue;
- windows_semaphore m_sem_block_lock;
- windows_mutex m_mtx_unblock_lock;
+ struct condition_data
+ {
+ typedef boost::int32_t integer_type;
+ typedef windows_semaphore semaphore_type;
+ typedef windows_mutex mutex_type;
+
+ condition_data()
+ : m_nwaiters_blocked(0)
+ , m_nwaiters_gone(0)
+ , m_nwaiters_to_unblock(0)
+ , m_sem_block_queue(0)
+ , m_sem_block_lock(1)
+ , m_mtx_unblock_lock()
+ {}
+
+ 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; }
+
+ boost::int32_t m_nwaiters_blocked;
+ boost::int32_t m_nwaiters_gone;
+ boost::int32_t m_nwaiters_to_unblock;
+ 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;
};
inline windows_condition::windows_condition()
- : m_nwaiters_blocked(0)
- , m_nwaiters_gone(0)
- , m_nwaiters_to_unblock(0)
- , m_sem_block_queue(0)
- , m_sem_block_lock(1)
- , m_mtx_unblock_lock()
+ : m_condition_data()
{}
inline windows_condition::~windows_condition()
{}
inline void windows_condition::notify_one()
-{ this->do_signal(false); }
+{ algorithm_type::signal(m_condition_data, false); }
inline void windows_condition::notify_all()
-{ this->do_signal(true); }
-
-inline void windows_condition::do_signal(bool broadcast)
-{
- boost::int32_t nsignals_to_issue;
-
- {
- scoped_lock<windows_mutex> locker(m_mtx_unblock_lock);
-
- if ( 0 != m_nwaiters_to_unblock ) { // the gate is closed!!!
- if ( 0 == m_nwaiters_blocked ) { // NO-OP
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- return;
- }
- if (broadcast) {
- m_nwaiters_to_unblock += nsignals_to_issue = m_nwaiters_blocked;
- m_nwaiters_blocked = 0;
- }
- else {
- nsignals_to_issue = 1;
- m_nwaiters_to_unblock++;
- m_nwaiters_blocked--;
- }
- }
- else if ( m_nwaiters_blocked > m_nwaiters_gone ) { // HARMLESS RACE CONDITION!
- m_sem_block_lock.wait(); // close the gate
- if ( 0 != m_nwaiters_gone ) {
- m_nwaiters_blocked -= m_nwaiters_gone;
- m_nwaiters_gone = 0;
- }
- if (broadcast) {
- nsignals_to_issue = m_nwaiters_to_unblock = m_nwaiters_blocked;
- m_nwaiters_blocked = 0;
- }
- else {
- nsignals_to_issue = m_nwaiters_to_unblock = 1;
- m_nwaiters_blocked--;
- }
- }
- else { // NO-OP
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- return;
- }
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- }
- m_sem_block_queue.post(nsignals_to_issue);
-}
+{ algorithm_type::signal(m_condition_data, true); }
template<class InterprocessMutex>
inline void windows_condition::do_wait(InterprocessMutex &mut)
-{ this->do_timed_wait(false, boost::posix_time::ptime(), 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 this->do_timed_wait(true, abs_time, mut); }
-
-template<class InterprocessMutex>
-inline bool windows_condition::do_timed_wait
- (bool tout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mtxExternal)
-{
- //Initialize to avoid warnings
- boost::int32_t nsignals_was_left = 0;
- boost::int32_t nwaiters_was_gone = 0;
-
- m_sem_block_lock.wait();
- ++m_nwaiters_blocked;
- m_sem_block_lock.post();
-
- struct scoped_unlock
- {
- InterprocessMutex & mut;
- scoped_unlock(InterprocessMutex & m)
- : mut(m)
- { m.unlock(); }
-
- ~scoped_unlock()
- { mut.lock(); }
- } unlocker(mtxExternal);
-
-
- bool bTimedOut = tout_enabled ? !m_sem_block_queue.timed_wait(abs_time) : (m_sem_block_queue.wait(), false);
-
- {
- scoped_lock<windows_mutex> locker(m_mtx_unblock_lock);
- if ( 0 != (nsignals_was_left = m_nwaiters_to_unblock) ) {
- if ( bTimedOut ) { // timeout (or canceled)
- if ( 0 != m_nwaiters_blocked ) {
- m_nwaiters_blocked--;
- }
- else {
- m_nwaiters_gone++; // count spurious wakeups.
- }
- }
- if ( 0 == --m_nwaiters_to_unblock ) {
- if ( 0 != m_nwaiters_blocked ) {
- m_sem_block_lock.post(); // open the gate.
- nsignals_was_left = 0; // do not open the gate below again.
- }
- else if ( 0 != (nwaiters_was_gone = m_nwaiters_gone) ) {
- m_nwaiters_gone = 0;
- }
- }
- }
- else if ( (std::numeric_limits<boost::int32_t>::max)()/2
- == ++m_nwaiters_gone ) { // timeout/canceled or spurious semaphore :-)
- m_sem_block_lock.wait();
- m_nwaiters_blocked -= m_nwaiters_gone; // something is going on here - test of timeouts? :-)
- m_sem_block_lock.post();
- m_nwaiters_gone = 0;
- }
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- }
-
- if ( 1 == nsignals_was_left ) {
- if ( 0 != nwaiters_was_gone ) {
- // sem_adjust( m_sem_block_queue,-nwaiters_was_gone );
- while ( nwaiters_was_gone-- ) {
- m_sem_block_queue.wait(); // better now than spurious later
- }
- }
- m_sem_block_lock.post(); // open the gate
- }
-
- //mtxExternal.lock(); called from unlocker
-
- return ( bTimedOut ) ? false : true;
-}
+{ return algorithm_type::wait(m_condition_data, true, abs_time, mut); }
} //namespace ipcdetail
} //namespace interprocess
diff --git a/boost/interprocess/sync/windows/mutex.hpp b/boost/interprocess/sync/windows/mutex.hpp
index 5eca522339..477acd396a 100644
--- a/boost/interprocess/sync/windows/mutex.hpp
+++ b/boost/interprocess/sync/windows/mutex.hpp
@@ -19,8 +19,9 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
-#include <boost/interprocess/detail/intermodule_singleton.hpp>
+#include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#include <boost/interprocess/sync/windows/sync_utils.hpp>
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -47,85 +48,61 @@ class windows_mutex
const sync_id id_;
};
-inline windows_mutex::windows_mutex()
- : id_()
+inline windows_mutex::windows_mutex()
+ : id_(this)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//Create mutex with the initial count
bool open_or_created;
- handles.obtain_mutex(this->id_, &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);
(void)open_or_created;
}
-inline windows_mutex::~windows_mutex()
+inline windows_mutex::~windows_mutex()
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
handles.destroy_handle(this->id_);
}
inline void windows_mutex::lock(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- unsigned long ret = winapi::wait_for_single_object(hnd, winapi::infinite_time);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ mut.lock();
}
inline bool windows_mutex::try_lock(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- unsigned long ret = winapi::wait_for_single_object(hnd, 0);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ return mut.try_lock();
}
inline bool windows_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- boost::posix_time::ptime now
- = boost::posix_time::microsec_clock::universal_time();
-
- unsigned long ms = (unsigned long)(abs_time-now).total_milliseconds();
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- unsigned long ret = winapi::wait_for_single_object(hnd, ms);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ return mut.timed_lock(abs_time);
}
inline void windows_mutex::unlock(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- int ret = winapi::release_mutex(hnd);
- (void)ret;
- assert(ret);
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ return mut.unlock();
}
} //namespace ipcdetail {
diff --git a/boost/interprocess/sync/windows/named_condition.hpp b/boost/interprocess/sync/windows/named_condition.hpp
new file mode 100644
index 0000000000..403e826178
--- /dev/null
+++ b/boost/interprocess/sync/windows/named_condition.hpp
@@ -0,0 +1,334 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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_HPP
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# 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
+{
+ /// @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);
+}
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_HPP
diff --git a/boost/interprocess/sync/windows/named_mutex.hpp b/boost/interprocess/sync/windows/named_mutex.hpp
new file mode 100644
index 0000000000..8ea6b3e1e4
--- /dev/null
+++ b/boost/interprocess/sync/windows/named_mutex.hpp
@@ -0,0 +1,175 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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_MUTEX_HPP
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_MUTEX_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# 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/sync_utils.hpp>
+#include <boost/interprocess/sync/windows/named_sync.hpp>
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
+#include <boost/interprocess/errors.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+
+
+class windows_named_mutex
+{
+ /// @cond
+
+ //Non-copyable
+ windows_named_mutex();
+ windows_named_mutex(const windows_named_mutex &);
+ windows_named_mutex &operator=(const windows_named_mutex &);
+ /// @endcond
+
+ public:
+ windows_named_mutex(create_only_t, const char *name, const permissions &perm = permissions());
+
+ windows_named_mutex(open_or_create_t, const char *name, const permissions &perm = permissions());
+
+ windows_named_mutex(open_only_t, const char *name);
+
+ ~windows_named_mutex();
+
+ void unlock();
+ void lock();
+ bool try_lock();
+ bool timed_lock(const boost::posix_time::ptime &abs_time);
+
+ static bool remove(const char *name);
+
+ /// @cond
+ private:
+ friend class interprocess_tester;
+ void dont_close_on_destruction();
+ winapi_mutex_wrapper m_mtx_wrapper;
+ windows_named_sync m_named_sync;
+
+ class named_mut_callbacks : public windows_named_sync_interface
+ {
+ public:
+ named_mut_callbacks(winapi_mutex_wrapper &mtx_wrapper)
+ : m_mtx_wrapper(mtx_wrapper)
+ {}
+
+ virtual std::size_t get_data_size() const
+ { return 0u; }
+
+ virtual const void *buffer_with_init_data_to_file()
+ { return 0; }
+
+ virtual const void *buffer_with_final_data_to_file()
+ { return 0; }
+
+ virtual void *buffer_to_store_init_data_from_file()
+ { return 0; }
+
+ virtual bool open(create_enum_t, const char *id_name)
+ {
+ std::string aux_str = "Global\\bipc.mut.";
+ aux_str += id_name;
+ //
+ permissions mut_perm;
+ mut_perm.set_unrestricted();
+ return m_mtx_wrapper.open_or_create(aux_str.c_str(), mut_perm);
+ }
+
+ virtual void close()
+ {
+ m_mtx_wrapper.close();
+ }
+
+ virtual ~named_mut_callbacks()
+ {}
+
+ private:
+ winapi_mutex_wrapper& m_mtx_wrapper;
+ };
+ /// @endcond
+};
+
+inline windows_named_mutex::~windows_named_mutex()
+{
+ named_mut_callbacks callbacks(m_mtx_wrapper);
+ m_named_sync.close(callbacks);
+}
+
+inline void windows_named_mutex::dont_close_on_destruction()
+{}
+
+inline windows_named_mutex::windows_named_mutex
+ (create_only_t, const char *name, const permissions &perm)
+ : m_mtx_wrapper()
+{
+ named_mut_callbacks callbacks(m_mtx_wrapper);
+ m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
+}
+
+inline windows_named_mutex::windows_named_mutex
+ (open_or_create_t, const char *name, const permissions &perm)
+ : m_mtx_wrapper()
+{
+ named_mut_callbacks callbacks(m_mtx_wrapper);
+ m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
+}
+
+inline windows_named_mutex::windows_named_mutex(open_only_t, const char *name)
+ : m_mtx_wrapper()
+{
+ named_mut_callbacks callbacks(m_mtx_wrapper);
+ m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
+}
+
+inline void windows_named_mutex::unlock()
+{
+ m_mtx_wrapper.unlock();
+}
+
+inline void windows_named_mutex::lock()
+{
+ m_mtx_wrapper.lock();
+}
+
+inline bool windows_named_mutex::try_lock()
+{
+ return m_mtx_wrapper.try_lock();
+}
+
+inline bool windows_named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
+{
+ return m_mtx_wrapper.timed_lock(abs_time);
+}
+
+inline bool windows_named_mutex::remove(const char *name)
+{
+ return windows_named_sync::remove(name);
+}
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_MUTEX_HPP \ No newline at end of file
diff --git a/boost/interprocess/sync/windows/named_recursive_mutex.hpp b/boost/interprocess/sync/windows/named_recursive_mutex.hpp
new file mode 100644
index 0000000000..cb2ef79ac1
--- /dev/null
+++ b/boost/interprocess/sync/windows/named_recursive_mutex.hpp
@@ -0,0 +1,58 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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_RECURSIVE_NAMED_MUTEX_HPP
+#define BOOST_INTERPROCESS_WINDOWS_RECURSIVE_NAMED_MUTEX_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/sync/windows/named_mutex.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+
+class windows_named_recursive_mutex
+ //Windows mutexes based on CreateMutex are already recursive...
+ : public windows_named_mutex
+{
+ /// @cond
+
+ //Non-copyable
+ windows_named_recursive_mutex();
+ windows_named_recursive_mutex(const windows_named_mutex &);
+ windows_named_recursive_mutex &operator=(const windows_named_mutex &);
+ /// @endcond
+
+ public:
+ windows_named_recursive_mutex(create_only_t, const char *name, const permissions &perm = permissions())
+ : windows_named_mutex(create_only_t(), name, perm)
+ {}
+
+ windows_named_recursive_mutex(open_or_create_t, const char *name, const permissions &perm = permissions())
+ : windows_named_mutex(open_or_create_t(), name, perm)
+ {}
+
+ windows_named_recursive_mutex(open_only_t, const char *name)
+ : windows_named_mutex(open_only_t(), name)
+ {}
+};
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_WINDOWS_RECURSIVE_NAMED_MUTEX_HPP
diff --git a/boost/interprocess/sync/windows/named_semaphore.hpp b/boost/interprocess/sync/windows/named_semaphore.hpp
new file mode 100644
index 0000000000..8f48d4df96
--- /dev/null
+++ b/boost/interprocess/sync/windows/named_semaphore.hpp
@@ -0,0 +1,178 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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_SEMAPHORE_HPP
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_SEMAPHORE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# 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>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+
+
+class windows_named_semaphore
+{
+ /// @cond
+
+ //Non-copyable
+ windows_named_semaphore();
+ windows_named_semaphore(const windows_named_semaphore &);
+ windows_named_semaphore &operator=(const windows_named_semaphore &);
+ /// @endcond
+
+ public:
+ windows_named_semaphore(create_only_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
+
+ windows_named_semaphore(open_or_create_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
+
+ windows_named_semaphore(open_only_t, const char *name);
+
+ ~windows_named_semaphore();
+
+ void post();
+ void wait();
+ bool try_wait();
+ bool timed_wait(const boost::posix_time::ptime &abs_time);
+
+ static bool remove(const char *name);
+
+ /// @cond
+ private:
+ friend class interprocess_tester;
+ void dont_close_on_destruction();
+ winapi_semaphore_wrapper m_sem_wrapper;
+ windows_named_sync m_named_sync;
+
+ class named_sem_callbacks : public windows_named_sync_interface
+ {
+ public:
+ typedef __int64 sem_count_t;
+ named_sem_callbacks(winapi_semaphore_wrapper &sem_wrapper, sem_count_t sem_cnt)
+ : m_sem_wrapper(sem_wrapper), m_sem_count(sem_cnt)
+ {}
+
+ virtual std::size_t get_data_size() const
+ { return sizeof(sem_count_t); }
+
+ virtual const void *buffer_with_final_data_to_file()
+ { return &m_sem_count; }
+
+ virtual const void *buffer_with_init_data_to_file()
+ { return &m_sem_count; }
+
+ virtual void *buffer_to_store_init_data_from_file()
+ { return &m_sem_count; }
+
+ virtual bool open(create_enum_t, const char *id_name)
+ {
+ std::string aux_str = "Global\\bipc.sem.";
+ aux_str += id_name;
+ //
+ permissions sem_perm;
+ sem_perm.set_unrestricted();
+ bool created;
+ return m_sem_wrapper.open_or_create
+ ( aux_str.c_str(), static_cast<long>(m_sem_count)
+ , winapi_semaphore_wrapper::MaxCount, sem_perm, created);
+ }
+
+ virtual void close()
+ {
+ m_sem_wrapper.close();
+ }
+
+ virtual ~named_sem_callbacks()
+ {}
+
+ private:
+ sem_count_t m_sem_count;
+ winapi_semaphore_wrapper& m_sem_wrapper;
+ };
+
+ /// @endcond
+};
+
+inline windows_named_semaphore::~windows_named_semaphore()
+{
+ named_sem_callbacks callbacks(m_sem_wrapper, m_sem_wrapper.value());
+ m_named_sync.close(callbacks);
+}
+
+inline void windows_named_semaphore::dont_close_on_destruction()
+{}
+
+inline windows_named_semaphore::windows_named_semaphore
+ (create_only_t, const char *name, unsigned int initial_count, const permissions &perm)
+ : m_sem_wrapper()
+{
+ named_sem_callbacks callbacks(m_sem_wrapper, initial_count);
+ m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
+}
+
+inline windows_named_semaphore::windows_named_semaphore
+ (open_or_create_t, const char *name, unsigned int initial_count, const permissions &perm)
+ : m_sem_wrapper()
+{
+ named_sem_callbacks callbacks(m_sem_wrapper, initial_count);
+ m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
+}
+
+inline windows_named_semaphore::windows_named_semaphore(open_only_t, const char *name)
+ : m_sem_wrapper()
+{
+ named_sem_callbacks callbacks(m_sem_wrapper, 0);
+ m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
+}
+
+inline void windows_named_semaphore::post()
+{
+ m_sem_wrapper.post();
+}
+
+inline void windows_named_semaphore::wait()
+{
+ m_sem_wrapper.wait();
+}
+
+inline bool windows_named_semaphore::try_wait()
+{
+ return m_sem_wrapper.try_wait();
+}
+
+inline bool windows_named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
+{
+ return m_sem_wrapper.timed_wait(abs_time);
+}
+
+inline bool windows_named_semaphore::remove(const char *name)
+{
+ return windows_named_sync::remove(name);
+}
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_SEMAPHORE_HPP
diff --git a/boost/interprocess/sync/windows/named_sync.hpp b/boost/interprocess/sync/windows/named_sync.hpp
new file mode 100644
index 0000000000..41f299f8eb
--- /dev/null
+++ b/boost/interprocess/sync/windows/named_sync.hpp
@@ -0,0 +1,215 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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_SYNC_HPP
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# 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/tmp_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>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+class windows_named_sync_interface
+{
+ public:
+ virtual std::size_t get_data_size() const = 0;
+ virtual const void *buffer_with_final_data_to_file() = 0;
+ virtual const void *buffer_with_init_data_to_file() = 0;
+ virtual void *buffer_to_store_init_data_from_file() = 0;
+ virtual bool open(create_enum_t creation_type, const char *id_name) = 0;
+ virtual void close() = 0;
+ virtual ~windows_named_sync_interface() = 0;
+};
+
+inline windows_named_sync_interface::~windows_named_sync_interface()
+{}
+
+class windows_named_sync
+{
+ /// @cond
+
+ //Non-copyable
+ windows_named_sync(const windows_named_sync &);
+ windows_named_sync &operator=(const windows_named_sync &);
+ /// @endcond
+
+ public:
+ windows_named_sync();
+ void open_or_create(create_enum_t creation_type, const char *name, const permissions &perm, windows_named_sync_interface &sync_interface);
+ void close(windows_named_sync_interface &sync_interface);
+
+ static bool remove(const char *name);
+
+ /// @cond
+ private:
+ void *m_file_hnd;
+
+ /// @endcond
+};
+
+inline windows_named_sync::windows_named_sync()
+ : m_file_hnd(winapi::invalid_handle_value)
+{}
+
+inline void windows_named_sync::close(windows_named_sync_interface &sync_interface)
+{
+ const std::size_t buflen = sync_interface.get_data_size();
+ const std::size_t sizeof_file_info = sizeof(sync_id::internal_type) + buflen;
+ winapi::interprocess_overlapped overlapped;
+ if(winapi::lock_file_ex
+ (m_file_hnd, winapi::lockfile_exclusive_lock, 0, sizeof_file_info, 0, &overlapped)){
+ if(winapi::set_file_pointer_ex(m_file_hnd, sizeof(sync_id::internal_type), 0, winapi::file_begin)){
+ const void *buf = sync_interface.buffer_with_final_data_to_file();
+
+ unsigned long written_or_read = 0;
+ if(winapi::write_file(m_file_hnd, buf, buflen, &written_or_read, 0)){
+ //...
+ }
+ }
+ }
+ sync_interface.close();
+ if(m_file_hnd != winapi::invalid_handle_value){
+ winapi::close_handle(m_file_hnd);
+ m_file_hnd = winapi::invalid_handle_value;
+ }
+}
+
+inline void windows_named_sync::open_or_create
+ ( create_enum_t creation_type
+ , const char *name
+ , const permissions &perm
+ , windows_named_sync_interface &sync_interface)
+{
+ std::string aux_str(name);
+ m_file_hnd = winapi::invalid_handle_value;
+ //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 a file with required permissions.
+ m_file_hnd = winapi::create_file
+ ( aux_str.c_str()
+ , winapi::generic_read | winapi::generic_write
+ , creation_type == DoOpen ? winapi::open_existing :
+ (creation_type == DoCreate ? winapi::create_new : winapi::open_always)
+ , 0
+ , (winapi::interprocess_security_attributes*)perm.get_permissions());
+
+ //Obtain OS error in case something has failed
+ error_info err;
+ bool success = false;
+ if(m_file_hnd != winapi::invalid_handle_value){
+ //Now lock the file
+ const std::size_t buflen = sync_interface.get_data_size();
+ typedef __int64 unique_id_type;
+ const std::size_t sizeof_file_info = sizeof(unique_id_type) + buflen;
+ winapi::interprocess_overlapped overlapped;
+ if(winapi::lock_file_ex
+ (m_file_hnd, winapi::lockfile_exclusive_lock, 0, sizeof_file_info, 0, &overlapped)){
+ __int64 filesize = 0;
+ //Obtain the unique id to open the native semaphore.
+ //If file size was created
+ if(winapi::get_file_size(m_file_hnd, filesize)){
+ unsigned long written_or_read = 0;
+ unique_id_type unique_id_val;
+ if(static_cast<std::size_t>(filesize) != sizeof_file_info){
+ winapi::set_end_of_file(m_file_hnd);
+ winapi::query_performance_counter(&unique_id_val);
+ const void *buf = sync_interface.buffer_with_init_data_to_file();
+ //Write unique ID in file. This ID will be used to calculate the semaphore name
+ if(winapi::write_file(m_file_hnd, &unique_id_val, sizeof(unique_id_val), &written_or_read, 0) &&
+ written_or_read == sizeof(unique_id_val) &&
+ winapi::write_file(m_file_hnd, buf, buflen, &written_or_read, 0) &&
+ written_or_read == buflen ){
+ success = true;
+ }
+ winapi::get_file_size(m_file_hnd, filesize);
+ assert(std::size_t(filesize) == sizeof_file_info);
+ }
+ else{
+ void *buf = sync_interface.buffer_to_store_init_data_from_file();
+ if(winapi::read_file(m_file_hnd, &unique_id_val, sizeof(unique_id_val), &written_or_read, 0) &&
+ written_or_read == sizeof(unique_id_val) &&
+ winapi::read_file(m_file_hnd, buf, buflen, &written_or_read, 0) &&
+ written_or_read == buflen ){
+ success = true;
+ }
+ }
+ if(success){
+ //Now create a global semaphore name based on the unique id
+ char unique_id_name[sizeof(unique_id_val)*2+1];
+ std::size_t name_suffix_length = sizeof(unique_id_name);
+ bytes_to_str(&unique_id_val, sizeof(unique_id_val), &unique_id_name[0], name_suffix_length);
+ success = sync_interface.open(creation_type, unique_id_name);
+ }
+ }
+
+ //Obtain OS error in case something has failed
+ err = system_error_code();
+
+ //If this fails we have no possible rollback so don't check the return
+ if(!winapi::unlock_file_ex(m_file_hnd, 0, sizeof_file_info, 0, &overlapped)){
+ err = system_error_code();
+ }
+ }
+ else{
+ //Obtain OS error in case something has failed
+ err = system_error_code();
+ }
+ }
+ else{
+ err = system_error_code();
+ }
+
+ if(!success){
+ if(m_file_hnd != winapi::invalid_handle_value){
+ winapi::close_handle(m_file_hnd);
+ m_file_hnd = winapi::invalid_handle_value;
+ }
+ //Throw as something went wrong
+ throw interprocess_exception(err);
+ }
+ }
+}
+
+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);
+ return winapi::unlink_file(semfile.c_str());
+ }
+ catch(...){
+ return false;
+ }
+}
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
diff --git a/boost/interprocess/sync/windows/semaphore.hpp b/boost/interprocess/sync/windows/semaphore.hpp
index d5835ceec7..af336df48a 100644
--- a/boost/interprocess/sync/windows/semaphore.hpp
+++ b/boost/interprocess/sync/windows/semaphore.hpp
@@ -19,8 +19,9 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
-#include <boost/interprocess/detail/intermodule_singleton.hpp>
+#include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#include <boost/interprocess/sync/windows/sync_utils.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -46,11 +47,11 @@ class windows_semaphore
const sync_id id_;
};
-inline windows_semaphore::windows_semaphore(unsigned int initialCount)
- : id_()
+inline windows_semaphore::windows_semaphore(unsigned int initialCount)
+ : id_(this)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//Force smeaphore creation with the initial count
bool open_or_created;
handles.obtain_semaphore(this->id_, initialCount, &open_or_created);
@@ -60,72 +61,46 @@ inline windows_semaphore::windows_semaphore(unsigned int initialCount)
(void)open_or_created;
}
-inline windows_semaphore::~windows_semaphore()
+inline windows_semaphore::~windows_semaphore()
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
handles.destroy_handle(this->id_);
}
inline void windows_semaphore::wait(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- unsigned long ret = winapi::wait_for_single_object(hnd, winapi::infinite_time);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ sem.wait();
}
inline bool windows_semaphore::try_wait(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- unsigned long ret = winapi::wait_for_single_object(hnd, 0);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ return sem.try_wait();
}
inline bool windows_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait();
- return true;
- }
- boost::posix_time::ptime now
- = boost::posix_time::microsec_clock::universal_time();
-
- unsigned long ms = (unsigned long)(abs_time-now).total_milliseconds();
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- unsigned long ret = winapi::wait_for_single_object(hnd, ms);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ return sem.timed_wait(abs_time);
}
inline void windows_semaphore::post(long release_count)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
- //This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- long prev_count;
- int ret = winapi::release_semaphore(hnd, release_count, &prev_count);
- (void)ret;
- assert(ret);
+ windows_intermodule_singleton<sync_handles>::get();
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ sem.post(release_count);
}
} //namespace ipcdetail {
diff --git a/boost/interprocess/sync/windows/sync_utils.hpp b/boost/interprocess/sync/windows/sync_utils.hpp
index 89c4aeda0b..0281da1266 100644
--- a/boost/interprocess/sync/windows/sync_utils.hpp
+++ b/boost/interprocess/sync/windows/sync_utils.hpp
@@ -21,7 +21,10 @@
#include <boost/interprocess/sync/spin/mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
#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>
+#include <boost/container/map.hpp>
#include <cstddef>
namespace boost {
@@ -32,6 +35,7 @@ inline bool bytes_to_str(const void *mem, const std::size_t mem_length, char *ou
{
const std::size_t need_mem = mem_length*2+1;
if(out_length < need_mem){
+ out_length = need_mem;
return false;
}
@@ -49,40 +53,57 @@ inline bool bytes_to_str(const void *mem, const std::size_t mem_length, char *ou
return true;
}
-struct sync_id
+class sync_id
{
- sync_id()
- { winapi::query_performance_counter(&rand); }
+ public:
+ typedef __int64 internal_type;
+ sync_id(const void *map_addr)
+ : map_addr_(map_addr)
+ { winapi::query_performance_counter(&rand_); }
+
+ explicit sync_id(internal_type val, const void *map_addr)
+ : map_addr_(map_addr)
+ { rand_ = val; }
+
+ const internal_type &internal_pod() const
+ { return rand_; }
- __int64 rand;
+ internal_type &internal_pod()
+ { return rand_; }
+
+ const void *map_addr() const
+ { return map_addr_; }
friend std::size_t hash_value(const sync_id &m)
- { return boost::hash_value(m.rand); }
+ { return boost::hash_value(m.rand_); }
friend bool operator==(const sync_id &l, const sync_id &r)
- { return l.rand == r.rand; }
-};
-/*
-#define BOOST_NO_LONG_LONG ss
+ { return l.rand_ == r.rand_ && l.map_addr_ == r.map_addr_; }
-#if defined(BOOST_NO_LONG_LONG)
+ private:
+ internal_type rand_;
+ const void * const map_addr_;
+};
-#error "defined(BOOST_NO_LONG_LONG)"
-#else
-#error "NOT defined(BOOST_NO_LONG_LONG)"
-#endif
-*/
class sync_handles
{
public:
enum type { MUTEX, SEMAPHORE };
private:
- typedef boost::unordered_map<sync_id, void*> map_type;
+ struct address_less
+ {
+ bool operator()(sync_id const * const l, sync_id const * const r) const
+ { return l->map_addr() < r->map_addr(); }
+ };
+
+ typedef boost::unordered_map<sync_id, void*> umap_type;
+ typedef boost::container::map<const sync_id*, umap_type::iterator, address_less> map_type;
static const std::size_t LengthOfGlobal = sizeof("Global\\boost.ipc")-1;
static const std::size_t StrSize = LengthOfGlobal + (sizeof(sync_id)*2+1);
typedef char NameBuf[StrSize];
+
void fill_name(NameBuf &name, const sync_id &id)
{
const char *n = "Global\\boost.ipc";
@@ -92,13 +113,12 @@ class sync_handles
++i;
} while(n[i]);
std::size_t len = sizeof(NameBuf) - LengthOfGlobal;
- bytes_to_str(&id.rand, sizeof(id.rand), &name[LengthOfGlobal], len);
+ bytes_to_str(&id.internal_pod(), sizeof(id.internal_pod()), &name[LengthOfGlobal], len);
}
- void erase_and_throw_if_error(void *hnd_val, const sync_id &id)
+ void throw_if_error(void *hnd_val)
{
if(!hnd_val){
- map_.erase(id);
error_info err(winapi::get_last_error());
throw interprocess_exception(err);
}
@@ -108,27 +128,36 @@ class sync_handles
{
NameBuf name;
fill_name(name, id);
- void *hnd_val = winapi::open_or_create_semaphore
- (name, (long)initial_count, (long)(((unsigned long)(-1))>>1), unrestricted_security.get_attributes());
- erase_and_throw_if_error(hnd_val, id);
- return hnd_val;
+ permissions unrestricted_security;
+ unrestricted_security.set_unrestricted();
+ winapi_semaphore_wrapper sem_wrapper;
+ bool created;
+ sem_wrapper.open_or_create
+ (name, (long)initial_count, winapi_semaphore_wrapper::MaxCount, unrestricted_security, created);
+ throw_if_error(sem_wrapper.handle());
+ return sem_wrapper.release();
}
void* open_or_create_mutex(const sync_id &id)
{
NameBuf name;
fill_name(name, id);
- void *hnd_val = winapi::open_or_create_mutex
- (name, false, unrestricted_security.get_attributes());
- erase_and_throw_if_error(hnd_val, id);
- return hnd_val;
+ permissions unrestricted_security;
+ unrestricted_security.set_unrestricted();
+ winapi_mutex_wrapper mtx_wrapper;
+ mtx_wrapper.open_or_create(name, unrestricted_security);
+ throw_if_error(mtx_wrapper.handle());
+ return mtx_wrapper.release();
}
public:
void *obtain_mutex(const sync_id &id, bool *popen_created = 0)
{
+ umap_type::value_type v(id, (void*)0);
scoped_lock<spin_mutex> lock(mtx_);
- void *&hnd_val = map_[id];
+ umap_type::iterator it = umap_.insert(v).first;
+ map_[&it->first] = it;
+ void *&hnd_val = it->second;
if(!hnd_val){
hnd_val = open_or_create_mutex(id);
if(popen_created) *popen_created = true;
@@ -138,8 +167,11 @@ class sync_handles
void *obtain_semaphore(const sync_id &id, unsigned int initial_count, bool *popen_created = 0)
{
+ umap_type::value_type v(id, (void*)0);
scoped_lock<spin_mutex> lock(mtx_);
- void *&hnd_val = map_[id];
+ umap_type::iterator it = umap_.insert(v).first;
+ map_[&it->first] = it;
+ void *&hnd_val = it->second;
if(!hnd_val){
hnd_val = open_or_create_semaphore(id, initial_count);
if(popen_created) *popen_created = true;
@@ -150,16 +182,35 @@ class sync_handles
void destroy_handle(const sync_id &id)
{
scoped_lock<spin_mutex> lock(mtx_);
- map_type::iterator it = map_.find(id);
- if(it != map_.end()){
+ umap_type::iterator it = umap_.find(id);
+ umap_type::iterator itend = umap_.end();
+
+ if(it != itend){
winapi::close_handle(it->second);
- map_.erase(it);
+ const map_type::key_type &k = &it->first;
+ map_.erase(k);
+ umap_.erase(it);
+ }
+ }
+
+ 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);
+ 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];
+ winapi::close_handle(hnd);
+ umap_.erase(*itlow->first);
+ itlow = map_.erase(itlow);
}
}
private:
- winapi::interprocess_all_access_security unrestricted_security;
spin_mutex mtx_;
+ umap_type umap_;
map_type map_;
};
diff --git a/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp b/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp
new file mode 100644
index 0000000000..0be96011cf
--- /dev/null
+++ b/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp
@@ -0,0 +1,163 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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_MUTEX_WRAPPER_HPP
+#define BOOST_INTERPROCESS_DETAIL_WINAPI_MUTEX_WRAPPER_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# 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/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 {
+
+class winapi_mutex_functions
+{
+ /// @cond
+
+ //Non-copyable
+ winapi_mutex_functions(const winapi_mutex_functions &);
+ winapi_mutex_functions &operator=(const winapi_mutex_functions &);
+ /// @endcond
+
+ public:
+ winapi_mutex_functions(void *mtx_hnd)
+ : m_mtx_hnd(mtx_hnd)
+ {}
+
+ void unlock()
+ {
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ bool timed_lock(const boost::posix_time::ptime &abs_time)
+ {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
+
+ 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
+ protected:
+ void *m_mtx_hnd;
+ /// @endcond
+};
+
+//Swappable mutex wrapper
+class winapi_mutex_wrapper
+ : public winapi_mutex_functions
+{
+ /// @cond
+
+ //Non-copyable
+ winapi_mutex_wrapper(const winapi_mutex_wrapper &);
+ winapi_mutex_wrapper &operator=(const winapi_mutex_wrapper &);
+ /// @endcond
+
+ public:
+ winapi_mutex_wrapper(void *mtx_hnd = winapi::invalid_handle_value)
+ : winapi_mutex_functions(mtx_hnd)
+ {}
+
+ ~winapi_mutex_wrapper()
+ { this->close(); }
+
+ void *release()
+ {
+ void *hnd = m_mtx_hnd;
+ m_mtx_hnd = winapi::invalid_handle_value;
+ return hnd;
+ }
+
+ void *handle() const
+ { return m_mtx_hnd; }
+
+ bool open_or_create(const char *name, const permissions &perm)
+ {
+ if(m_mtx_hnd == winapi::invalid_handle_value){
+ 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;
+ }
+ else{
+ return false;
+ }
+ }
+
+ void close()
+ {
+ if(m_mtx_hnd != winapi::invalid_handle_value){
+ winapi::close_handle(m_mtx_hnd);
+ m_mtx_hnd = winapi::invalid_handle_value;
+ }
+ }
+
+ void swap(winapi_mutex_wrapper &other)
+ { void *tmp = m_mtx_hnd; m_mtx_hnd = other.m_mtx_hnd; other.m_mtx_hnd = tmp; }
+};
+
+} //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/windows/winapi_semaphore_wrapper.hpp b/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp
new file mode 100644
index 0000000000..2dd7845627
--- /dev/null
+++ b/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp
@@ -0,0 +1,198 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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_SEMAPHORE_WRAPPER_HPP
+#define BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# 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/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 {
+
+class winapi_semaphore_functions
+{
+ /// @cond
+
+ //Non-copyable
+ winapi_semaphore_functions(const winapi_semaphore_functions &);
+ winapi_semaphore_functions &operator=(const winapi_semaphore_functions &);
+ /// @endcond
+
+ public:
+ winapi_semaphore_functions(void *hnd)
+ : m_sem_hnd(hnd)
+ {}
+
+ void post(long count = 1)
+ {
+ long prev_count;
+ winapi::release_semaphore(m_sem_hnd, count, &prev_count);
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ long value() const
+ {
+ long count, limit;
+ if(!winapi::get_semaphore_info(m_sem_hnd, count, limit))
+ return 0;
+ return count;
+ }
+
+ long limit() const
+ {
+ long count, limit;
+ if(!winapi::get_semaphore_info(m_sem_hnd, count, limit))
+ return 0;
+ return limit;
+ }
+
+ /// @cond
+ protected:
+ void *m_sem_hnd;
+ /// @endcond
+};
+
+
+//Swappable semaphore wrapper
+class winapi_semaphore_wrapper
+ : public winapi_semaphore_functions
+{
+ winapi_semaphore_wrapper(const winapi_semaphore_wrapper &);
+ winapi_semaphore_wrapper &operator=(const winapi_semaphore_wrapper &);
+
+ public:
+
+ //Long is 32 bits in windows
+ static const long MaxCount = long(0x7FFFFFFF);
+
+ winapi_semaphore_wrapper(void *hnd = winapi::invalid_handle_value)
+ : winapi_semaphore_functions(hnd)
+ {}
+
+ ~winapi_semaphore_wrapper()
+ { this->close(); }
+
+ void *release()
+ {
+ void *hnd = m_sem_hnd;
+ m_sem_hnd = winapi::invalid_handle_value;
+ return hnd;
+ }
+
+ void *handle() const
+ { return m_sem_hnd; }
+
+ bool open_or_create( const char *name
+ , long sem_count
+ , long max_count
+ , const permissions &perm
+ , bool &created)
+ {
+ if(m_sem_hnd == winapi::invalid_handle_value){
+ m_sem_hnd = winapi::open_or_create_semaphore
+ ( name
+ , sem_count
+ , max_count
+ , (winapi::interprocess_security_attributes*)perm.get_permissions()
+ );
+ created = winapi::get_last_error() != winapi::error_already_exists;
+ return m_sem_hnd != winapi::invalid_handle_value;
+ }
+ else{
+ return false;
+ }
+ }
+
+ bool open_semaphore(const char *name)
+ {
+ if(m_sem_hnd == winapi::invalid_handle_value){
+ m_sem_hnd = winapi::open_semaphore(name);
+ return m_sem_hnd != winapi::invalid_handle_value;
+ }
+ else{
+ return false;
+ }
+ }
+
+ void close()
+ {
+ if(m_sem_hnd != winapi::invalid_handle_value){
+ winapi::close_handle(m_sem_hnd);
+ m_sem_hnd = winapi::invalid_handle_value;
+ }
+ }
+
+ void swap(winapi_semaphore_wrapper &other)
+ { void *tmp = m_sem_hnd; m_sem_hnd = other.m_sem_hnd; other.m_sem_hnd = tmp; }
+};
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
diff --git a/boost/interprocess/sync/xsi/xsi_named_mutex.hpp b/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
index 3dffdcc2ed..485b1ac101 100644
--- a/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
+++ b/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
@@ -62,20 +62,20 @@ class xsi_named_mutex
xsi_named_mutex(open_or_create_t, const char *path, boost::uint8_t id, int perm = 0666)
{ this->priv_open_or_create(ipcdetail::DoOpenOrCreate, path, id, perm); }
- //!Moves the ownership of "moved"'s named mutex to *this.
- //!After the call, "moved" does not represent any named mutex
+ //!Moves the ownership of "moved"'s named mutex to *this.
+ //!After the call, "moved" does not represent any named mutex
//!Does not throw
xsi_named_mutex(BOOST_RV_REF(xsi_named_mutex) moved)
{ this->swap(moved); }
//!Moves the ownership of "moved"'s named mutex to *this.
- //!After the call, "moved" does not represent any 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
@@ -126,11 +126,11 @@ class xsi_named_mutex
/// @cond
-inline xsi_named_mutex::xsi_named_mutex()
+inline xsi_named_mutex::xsi_named_mutex()
: m_semid(-1), m_key(-1), m_id(0), m_perm(0), m_path()
{}
-inline xsi_named_mutex::~xsi_named_mutex()
+inline xsi_named_mutex::~xsi_named_mutex()
{ this->priv_close(); }
inline const char *xsi_named_mutex::get_path() const
@@ -142,7 +142,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