update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -21,8 +21,8 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/sync/cv_status.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -35,17 +35,17 @@ namespace boost {
namespace interprocess {
namespace ipcdetail {
class windows_condition
class winapi_condition
{
windows_condition(const windows_condition &);
windows_condition &operator=(const windows_condition &);
winapi_condition(const winapi_condition &);
winapi_condition &operator=(const winapi_condition &);
public:
windows_condition()
winapi_condition()
: m_condition_data()
{}
~windows_condition()
~winapi_condition()
{
//Notify all waiting threads
//to allow POSIX semantics on condition destruction
@@ -58,14 +58,6 @@ class windows_condition
void notify_all()
{ m_condition_data.notify_all(); }
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
{ return m_condition_data.timed_wait(lock, abs_time); }
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
{ return m_condition_data.timed_wait(lock, abs_time, pred); }
template <typename L>
void wait(L& lock)
{ m_condition_data.wait(lock); }
@@ -74,13 +66,38 @@ class windows_condition
void wait(L& lock, Pr pred)
{ m_condition_data.wait(lock, pred); }
template <typename L, typename TimePoint>
bool timed_wait(L& lock, const TimePoint &abs_time)
{ return m_condition_data.timed_wait(lock, abs_time); }
template <typename L, typename TimePoint, typename Pr>
bool timed_wait(L& lock, const TimePoint &abs_time, Pr pred)
{ return m_condition_data.timed_wait(lock, abs_time, pred); }
template <typename L, class TimePoint>
cv_status wait_until(L& lock, const TimePoint &abs_time)
{ return this->timed_wait(lock, abs_time) ? cv_status::no_timeout : cv_status::timeout; }
template <typename L, class TimePoint, typename Pr>
bool wait_until(L& lock, const TimePoint &abs_time, Pr pred)
{ return this->timed_wait(lock, abs_time, pred); }
template <typename L, class Duration>
cv_status wait_for(L& lock, const Duration &dur)
{ return this->wait_until(lock, duration_to_ustime(dur)); }
template <typename L, class Duration, typename Pr>
bool wait_for(L& lock, const Duration &dur, Pr pred)
{ return this->wait_until(lock, duration_to_ustime(dur), pred); }
private:
struct condition_data
{
typedef boost::int32_t integer_type;
typedef windows_semaphore semaphore_type;
typedef windows_mutex mutex_type;
typedef unsigned int integer_type;
typedef winapi_semaphore semaphore_type;
typedef winapi_mutex mutex_type;
condition_data()
: m_nwaiters_blocked(0)
@@ -109,12 +126,12 @@ class windows_condition
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;
integer_type m_nwaiters_blocked;
integer_type m_nwaiters_gone;
integer_type m_nwaiters_to_unblock;
semaphore_type m_sem_block_queue;
semaphore_type m_sem_block_lock;
mutex_type m_mtx_unblock_lock;
};
ipcdetail::condition_8a_wrapper<condition_data> m_condition_data;

View File

@@ -21,7 +21,6 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
#include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#include <boost/interprocess/sync/windows/sync_utils.hpp>
@@ -33,18 +32,25 @@ namespace boost {
namespace interprocess {
namespace ipcdetail {
class windows_mutex
class winapi_mutex
{
windows_mutex(const windows_mutex &);
windows_mutex &operator=(const windows_mutex &);
winapi_mutex(const winapi_mutex &);
winapi_mutex &operator=(const winapi_mutex &);
public:
windows_mutex();
~windows_mutex();
winapi_mutex();
~winapi_mutex();
void lock();
bool try_lock();
bool timed_lock(const boost::posix_time::ptime &abs_time);
template<class TimePoint> bool timed_lock(const TimePoint &abs_time);
template<class TimePoint> bool try_lock_until(const TimePoint &abs_time)
{ return this->timed_lock(abs_time); }
template<class Duration> bool try_lock_for(const Duration &dur)
{ return this->timed_lock(duration_to_ustime(dur)); }
void unlock();
void take_ownership(){};
@@ -52,60 +58,61 @@ class windows_mutex
const sync_id id_;
};
inline windows_mutex::windows_mutex()
: id_(this)
inline winapi_mutex::winapi_mutex()
: id_()
{
sync_handles &handles =
windows_intermodule_singleton<sync_handles>::get();
//Create mutex with the initial count
bool open_or_created;
(void)handles.obtain_mutex(this->id_, &open_or_created);
(void)handles.obtain_mutex(this->id_, this, &open_or_created);
//The mutex must be created, never opened
BOOST_ASSERT(open_or_created);
BOOST_ASSERT(open_or_created && winapi::get_last_error() != winapi::error_already_exists);
(void)open_or_created;
}
inline windows_mutex::~windows_mutex()
inline winapi_mutex::~winapi_mutex()
{
sync_handles &handles =
windows_intermodule_singleton<sync_handles>::get();
handles.destroy_handle(this->id_);
handles.destroy_handle(this->id_, this);
}
inline void windows_mutex::lock(void)
inline void winapi_mutex::lock(void)
{
sync_handles &handles =
windows_intermodule_singleton<sync_handles>::get();
//This can throw
winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
winapi_mutex_functions mut(handles.obtain_mutex(this->id_, this));
mut.lock();
}
inline bool windows_mutex::try_lock(void)
inline bool winapi_mutex::try_lock(void)
{
sync_handles &handles =
windows_intermodule_singleton<sync_handles>::get();
//This can throw
winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
winapi_mutex_functions mut(handles.obtain_mutex(this->id_, this));
return mut.try_lock();
}
inline bool windows_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
template<class TimePoint>
inline bool winapi_mutex::timed_lock(const TimePoint &abs_time)
{
sync_handles &handles =
windows_intermodule_singleton<sync_handles>::get();
//This can throw
winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
winapi_mutex_functions mut(handles.obtain_mutex(this->id_, this));
return mut.timed_lock(abs_time);
}
inline void windows_mutex::unlock(void)
inline void winapi_mutex::unlock(void)
{
sync_handles &handles =
windows_intermodule_singleton<sync_handles>::get();
//This can throw
winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
winapi_mutex_functions mut(handles.obtain_mutex(this->id_, this));
return mut.unlock();
}

View File

@@ -21,13 +21,15 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/sync/cv_status.hpp>
#include <boost/interprocess/sync/windows/named_condition_any.hpp>
namespace boost {
namespace interprocess {
namespace ipcdetail {
typedef windows_named_condition_any windows_named_condition;
typedef winapi_named_condition_any winapi_named_condition;
} //namespace ipcdetail {
} //namespace interprocess {

View File

@@ -21,10 +21,11 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/sync/cv_status.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>
@@ -33,41 +34,103 @@ namespace boost {
namespace interprocess {
namespace ipcdetail {
class windows_named_condition_any
template<class CharT>
struct named_cond_callbacks_str;
template<>
struct named_cond_callbacks_str<char>
{
static const char* ipc_cond()
{ return "Global\\bipc.cond."; }
static const char* bq()
{ return "_bq"; }
static const char* bl()
{ return "_bl"; }
static const char* ul()
{ return "_ul"; }
};
template<>
struct named_cond_callbacks_str<wchar_t>
{
static const wchar_t* ipc_cond()
{ return L"Global\\bipc.cond."; }
static const wchar_t* bq()
{ return L"_bq"; }
static const wchar_t* bl()
{ return L"_bl"; }
static const wchar_t* ul()
{ return L"_ul"; }
};
class winapi_named_condition_any
{
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
windows_named_condition_any();
windows_named_condition_any(const windows_named_condition_any &);
windows_named_condition_any &operator=(const windows_named_condition_any &);
winapi_named_condition_any();
winapi_named_condition_any(const winapi_named_condition_any &);
winapi_named_condition_any &operator=(const winapi_named_condition_any &);
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
windows_named_condition_any
(create_only_t, const char *name, const permissions &perm)
winapi_named_condition_any
(create_only_t, const char *name, const permissions &perm = permissions())
: m_condition_data()
{
named_cond_callbacks callbacks(m_condition_data.get_members());
m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
}
windows_named_condition_any
(open_or_create_t, const char *name, const permissions &perm)
winapi_named_condition_any
(open_or_create_t, const char *name, const permissions &perm = permissions())
: m_condition_data()
{
named_cond_callbacks callbacks(m_condition_data.get_members());
m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
}
windows_named_condition_any(open_only_t, const char *name)
winapi_named_condition_any(open_only_t, const char *name)
: m_condition_data()
{
named_cond_callbacks callbacks(m_condition_data.get_members());
m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
}
~windows_named_condition_any()
#if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
winapi_named_condition_any
(create_only_t, const wchar_t *name, const permissions &perm = permissions())
: m_condition_data()
{
named_cond_callbacks callbacks(m_condition_data.get_members());
m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
}
winapi_named_condition_any
(open_or_create_t, const wchar_t *name, const permissions &perm = permissions())
: m_condition_data()
{
named_cond_callbacks callbacks(m_condition_data.get_members());
m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
}
winapi_named_condition_any(open_only_t, const wchar_t *name)
: m_condition_data()
{
named_cond_callbacks callbacks(m_condition_data.get_members());
m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
}
#endif //defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
~winapi_named_condition_any()
{
named_cond_callbacks callbacks(m_condition_data.get_members());
m_named_sync.close(callbacks);
@@ -79,12 +142,12 @@ class windows_named_condition_any
void notify_all()
{ m_condition_data.notify_all(); }
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
template <typename L, typename TimePoint>
bool timed_wait(L& lock, const TimePoint &abs_time)
{ return m_condition_data.timed_wait(lock, abs_time); }
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
template <typename L, typename TimePoint, typename Pr>
bool timed_wait(L& lock, const TimePoint &abs_time, Pr pred)
{ return m_condition_data.timed_wait(lock, abs_time, pred); }
template <typename L>
@@ -95,9 +158,28 @@ class windows_named_condition_any
void wait(L& lock, Pr pred)
{ m_condition_data.wait(lock, pred); }
template <typename L, class TimePoint>
cv_status wait_until(L& lock, const TimePoint &abs_time)
{ return this->timed_wait(lock, abs_time) ? cv_status::no_timeout : cv_status::timeout; }
template <typename L, class TimePoint, typename Pr>
bool wait_until(L& lock, const TimePoint &abs_time, Pr pred)
{ return this->timed_wait(lock, abs_time, pred); }
template <typename L, class Duration>
cv_status wait_for(L& lock, const Duration &dur)
{ return this->wait_until(lock, ipcdetail::duration_to_ustime(dur)); }
template <typename L, class Duration, typename Pr>
bool wait_for(L& lock, const Duration &dur, Pr pred)
{ return this->wait_until(lock, ipcdetail::duration_to_ustime(dur), pred); }
static bool remove(const char *name)
{ return windows_named_sync::remove(name); }
static bool remove(const wchar_t *name)
{ return windows_named_sync::remove(name); }
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
@@ -138,6 +220,7 @@ class windows_named_condition_any
winapi_mutex_wrapper m_mtx_unblock_lock;
};
class named_cond_callbacks : public windows_named_sync_interface
{
typedef __int64 sem_count_t;
@@ -148,28 +231,51 @@ class windows_named_condition_any
: m_condition_data(cond_data)
{}
virtual std::size_t get_data_size() const
virtual std::size_t get_data_size() const BOOST_OVERRIDE
{ return sizeof(sem_counts); }
virtual const void *buffer_with_final_data_to_file()
virtual const void *buffer_with_final_data_to_file() BOOST_OVERRIDE
{
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()
virtual const void *buffer_with_init_data_to_file() BOOST_OVERRIDE
{
sem_counts[0] = 0;
sem_counts[1] = 1;
return &sem_counts;
}
virtual void *buffer_to_store_init_data_from_file()
virtual void *buffer_to_store_init_data_from_file() BOOST_OVERRIDE
{ return &sem_counts; }
virtual bool open(create_enum_t, const char *id_name)
virtual bool open(create_enum_t op, const char *id_name) BOOST_OVERRIDE
{ return this->open_impl(op, id_name); }
virtual bool open(create_enum_t op, const wchar_t *id_name) BOOST_OVERRIDE
{ return this->open_impl(op, id_name); }
virtual void close() BOOST_OVERRIDE
{
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() BOOST_OVERRIDE
{}
private:
template<class CharT>
bool open_impl(create_enum_t, const CharT *id_name)
{
typedef named_cond_callbacks_str<CharT> str_t;
m_condition_data.m_nwaiters_blocked = 0;
m_condition_data.m_nwaiters_gone = 0;
m_condition_data.m_nwaiters_to_unblock = 0;
@@ -179,29 +285,29 @@ class windows_named_condition_any
//initialization and cleanup in case any opening fails
permissions perm;
perm.set_unrestricted();
std::string aux_str = "Global\\bipc.cond.";
std::basic_string<CharT> aux_str = str_t::ipc_cond();
aux_str += id_name;
std::size_t pos = aux_str.size();
//sem_block_queue
aux_str += "_bq";
aux_str += str_t::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))
(aux_str.c_str(), static_cast<long>(sem_counts[0]), winapi_semaphore_wrapper::MaxCount, perm, created))
return false;
aux_str.erase(pos);
//sem_block_lock
aux_str += "_bl";
aux_str += str_t::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))
(aux_str.c_str(), static_cast<long>(sem_counts[1]), winapi_semaphore_wrapper::MaxCount, perm, created))
return false;
aux_str.erase(pos);
//mtx_unblock_lock
aux_str += "_ul";
aux_str += str_t::ul();
winapi_mutex_wrapper mtx_unblock_lock;
if(!mtx_unblock_lock.open_or_create(aux_str.c_str(), perm))
return false;
@@ -213,20 +319,6 @@ class windows_named_condition_any
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;
};

View File

@@ -23,7 +23,6 @@
#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>
@@ -37,32 +36,46 @@ namespace ipcdetail {
class windows_named_mutex
class winapi_named_mutex
{
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
windows_named_mutex();
windows_named_mutex(const windows_named_mutex &);
windows_named_mutex &operator=(const windows_named_mutex &);
winapi_named_mutex();
winapi_named_mutex(const winapi_named_mutex &);
winapi_named_mutex &operator=(const winapi_named_mutex &);
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
windows_named_mutex(create_only_t, const char *name, const permissions &perm = permissions());
winapi_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());
winapi_named_mutex(open_or_create_t, const char *name, const permissions &perm = permissions());
windows_named_mutex(open_only_t, const char *name);
winapi_named_mutex(open_only_t, const char *name);
~windows_named_mutex();
winapi_named_mutex(create_only_t, const wchar_t *name, const permissions &perm = permissions());
winapi_named_mutex(open_or_create_t, const wchar_t *name, const permissions &perm = permissions());
winapi_named_mutex(open_only_t, const wchar_t *name);
~winapi_named_mutex();
void unlock();
void lock();
bool try_lock();
bool timed_lock(const boost::posix_time::ptime &abs_time);
template<class TimePoint> bool timed_lock(const TimePoint &abs_time);
template<class TimePoint> bool try_lock_until(const TimePoint &abs_time)
{ return this->timed_lock(abs_time); }
template<class Duration> bool try_lock_for(const Duration &dur)
{ return this->timed_lock(duration_to_ustime(dur)); }
static bool remove(const char *name);
static bool remove(const wchar_t *name);
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
friend class interprocess_tester;
@@ -77,19 +90,19 @@ class windows_named_mutex
: m_mtx_wrapper(mtx_wrapper)
{}
virtual std::size_t get_data_size() const
virtual std::size_t get_data_size() const BOOST_OVERRIDE
{ return 0u; }
virtual const void *buffer_with_init_data_to_file()
virtual const void *buffer_with_init_data_to_file() BOOST_OVERRIDE
{ return 0; }
virtual const void *buffer_with_final_data_to_file()
virtual const void *buffer_with_final_data_to_file() BOOST_OVERRIDE
{ return 0; }
virtual void *buffer_to_store_init_data_from_file()
virtual void *buffer_to_store_init_data_from_file() BOOST_OVERRIDE
{ return 0; }
virtual bool open(create_enum_t, const char *id_name)
virtual bool open(create_enum_t, const char *id_name) BOOST_OVERRIDE
{
std::string aux_str = "Global\\bipc.mut.";
aux_str += id_name;
@@ -99,12 +112,22 @@ class windows_named_mutex
return m_mtx_wrapper.open_or_create(aux_str.c_str(), mut_perm);
}
virtual void close()
virtual bool open(create_enum_t, const wchar_t *id_name) BOOST_OVERRIDE
{
std::wstring aux_str = L"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() BOOST_OVERRIDE
{
m_mtx_wrapper.close();
}
virtual ~named_mut_callbacks()
virtual ~named_mut_callbacks() BOOST_OVERRIDE
{}
private:
@@ -113,16 +136,16 @@ class windows_named_mutex
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
inline windows_named_mutex::~windows_named_mutex()
inline winapi_named_mutex::~winapi_named_mutex()
{
named_mut_callbacks callbacks(m_mtx_wrapper);
m_named_sync.close(callbacks);
}
inline void windows_named_mutex::dont_close_on_destruction()
inline void winapi_named_mutex::dont_close_on_destruction()
{}
inline windows_named_mutex::windows_named_mutex
inline winapi_named_mutex::winapi_named_mutex
(create_only_t, const char *name, const permissions &perm)
: m_mtx_wrapper()
{
@@ -130,7 +153,7 @@ inline windows_named_mutex::windows_named_mutex
m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
}
inline windows_named_mutex::windows_named_mutex
inline winapi_named_mutex::winapi_named_mutex
(open_or_create_t, const char *name, const permissions &perm)
: m_mtx_wrapper()
{
@@ -138,34 +161,63 @@ inline windows_named_mutex::windows_named_mutex
m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
}
inline windows_named_mutex::windows_named_mutex(open_only_t, const char *name)
inline winapi_named_mutex::winapi_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()
inline winapi_named_mutex::winapi_named_mutex
(create_only_t, const wchar_t *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 winapi_named_mutex::winapi_named_mutex
(open_or_create_t, const wchar_t *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 winapi_named_mutex::winapi_named_mutex(open_only_t, const wchar_t *name)
: m_mtx_wrapper()
{
named_mut_callbacks callbacks(m_mtx_wrapper);
m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
}
inline void winapi_named_mutex::unlock()
{
m_mtx_wrapper.unlock();
}
inline void windows_named_mutex::lock()
inline void winapi_named_mutex::lock()
{
m_mtx_wrapper.lock();
}
inline bool windows_named_mutex::try_lock()
inline bool winapi_named_mutex::try_lock()
{
return m_mtx_wrapper.try_lock();
}
inline bool windows_named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
template<class TimePoint>
inline bool winapi_named_mutex::timed_lock(const TimePoint &abs_time)
{
return m_mtx_wrapper.timed_lock(abs_time);
}
inline bool windows_named_mutex::remove(const char *name)
inline bool winapi_named_mutex::remove(const char *name)
{
return windows_named_sync::remove(name);
}
inline bool winapi_named_mutex::remove(const wchar_t *name)
{
return windows_named_sync::remove(name);
}

View File

@@ -27,29 +27,41 @@ namespace interprocess {
namespace ipcdetail {
class windows_named_recursive_mutex
class winapi_named_recursive_mutex
//Windows mutexes based on CreateMutex are already recursive...
: public windows_named_mutex
: public winapi_named_mutex
{
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
windows_named_recursive_mutex();
windows_named_recursive_mutex(const windows_named_mutex &);
windows_named_recursive_mutex &operator=(const windows_named_mutex &);
winapi_named_recursive_mutex();
winapi_named_recursive_mutex(const winapi_named_mutex &);
winapi_named_recursive_mutex &operator=(const winapi_named_mutex &);
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
windows_named_recursive_mutex(create_only_t, const char *name, const permissions &perm = permissions())
: windows_named_mutex(create_only_t(), name, perm)
winapi_named_recursive_mutex(create_only_t, const char *name, const permissions &perm = permissions())
: winapi_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)
winapi_named_recursive_mutex(open_or_create_t, const char *name, const permissions &perm = permissions())
: winapi_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)
winapi_named_recursive_mutex(open_only_t, const char *name)
: winapi_named_mutex(open_only_t(), name)
{}
winapi_named_recursive_mutex(create_only_t, const wchar_t *name, const permissions &perm = permissions())
: winapi_named_mutex(create_only_t(), name, perm)
{}
winapi_named_recursive_mutex(open_or_create_t, const wchar_t *name, const permissions &perm = permissions())
: winapi_named_mutex(open_or_create_t(), name, perm)
{}
winapi_named_recursive_mutex(open_only_t, const wchar_t *name)
: winapi_named_mutex(open_only_t(), name)
{}
};

View File

@@ -24,7 +24,6 @@
#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>
@@ -34,31 +33,38 @@ namespace ipcdetail {
class windows_named_semaphore
class winapi_named_semaphore
{
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
//Non-copyable
windows_named_semaphore();
windows_named_semaphore(const windows_named_semaphore &);
windows_named_semaphore &operator=(const windows_named_semaphore &);
winapi_named_semaphore();
winapi_named_semaphore(const winapi_named_semaphore &);
winapi_named_semaphore &operator=(const winapi_named_semaphore &);
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
windows_named_semaphore(create_only_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
winapi_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());
winapi_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);
winapi_named_semaphore(open_only_t, const char *name);
~windows_named_semaphore();
winapi_named_semaphore(create_only_t, const wchar_t *name, unsigned int initialCount, const permissions &perm = permissions());
winapi_named_semaphore(open_or_create_t, const wchar_t *name, unsigned int initialCount, const permissions &perm = permissions());
winapi_named_semaphore(open_only_t, const wchar_t *name);
~winapi_named_semaphore();
void post();
void wait();
bool try_wait();
bool timed_wait(const boost::posix_time::ptime &abs_time);
template<class TimePoint> bool timed_wait(const TimePoint &abs_time);
static bool remove(const char *name);
static bool remove(const wchar_t *name);
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
@@ -75,19 +81,19 @@ class windows_named_semaphore
: m_sem_wrapper(sem_wrapper), m_sem_count(sem_cnt)
{}
virtual std::size_t get_data_size() const
virtual std::size_t get_data_size() const BOOST_OVERRIDE
{ return sizeof(sem_count_t); }
virtual const void *buffer_with_final_data_to_file()
virtual const void *buffer_with_final_data_to_file() BOOST_OVERRIDE
{ return &m_sem_count; }
virtual const void *buffer_with_init_data_to_file()
virtual const void *buffer_with_init_data_to_file() BOOST_OVERRIDE
{ return &m_sem_count; }
virtual void *buffer_to_store_init_data_from_file()
virtual void *buffer_to_store_init_data_from_file() BOOST_OVERRIDE
{ return &m_sem_count; }
virtual bool open(create_enum_t, const char *id_name)
virtual bool open(create_enum_t, const char *id_name) BOOST_OVERRIDE
{
std::string aux_str = "Global\\bipc.sem.";
aux_str += id_name;
@@ -100,32 +106,45 @@ class windows_named_semaphore
, winapi_semaphore_wrapper::MaxCount, sem_perm, created);
}
virtual void close()
virtual bool open(create_enum_t, const wchar_t *id_name) BOOST_OVERRIDE
{
std::wstring aux_str = L"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() BOOST_OVERRIDE
{
m_sem_wrapper.close();
}
virtual ~named_sem_callbacks()
virtual ~named_sem_callbacks() BOOST_OVERRIDE
{}
private:
sem_count_t m_sem_count;
winapi_semaphore_wrapper& m_sem_wrapper;
sem_count_t m_sem_count;
};
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
};
inline windows_named_semaphore::~windows_named_semaphore()
inline winapi_named_semaphore::~winapi_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 void winapi_named_semaphore::dont_close_on_destruction()
{}
inline windows_named_semaphore::windows_named_semaphore
inline winapi_named_semaphore::winapi_named_semaphore
(create_only_t, const char *name, unsigned int initial_count, const permissions &perm)
: m_sem_wrapper()
{
@@ -133,7 +152,7 @@ inline windows_named_semaphore::windows_named_semaphore
m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
}
inline windows_named_semaphore::windows_named_semaphore
inline winapi_named_semaphore::winapi_named_semaphore
(open_or_create_t, const char *name, unsigned int initial_count, const permissions &perm)
: m_sem_wrapper()
{
@@ -141,34 +160,63 @@ inline windows_named_semaphore::windows_named_semaphore
m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
}
inline windows_named_semaphore::windows_named_semaphore(open_only_t, const char *name)
inline winapi_named_semaphore::winapi_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()
inline winapi_named_semaphore::winapi_named_semaphore
(create_only_t, const wchar_t *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 winapi_named_semaphore::winapi_named_semaphore
(open_or_create_t, const wchar_t *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 winapi_named_semaphore::winapi_named_semaphore(open_only_t, const wchar_t *name)
: m_sem_wrapper()
{
named_sem_callbacks callbacks(m_sem_wrapper, 0);
m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
}
inline void winapi_named_semaphore::post()
{
m_sem_wrapper.post();
}
inline void windows_named_semaphore::wait()
inline void winapi_named_semaphore::wait()
{
m_sem_wrapper.wait();
}
inline bool windows_named_semaphore::try_wait()
inline bool winapi_named_semaphore::try_wait()
{
return m_sem_wrapper.try_wait();
}
inline bool windows_named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
template<class TimePoint>
inline bool winapi_named_semaphore::timed_wait(const TimePoint &abs_time)
{
return m_sem_wrapper.timed_wait(abs_time);
}
inline bool windows_named_semaphore::remove(const char *name)
inline bool winapi_named_semaphore::remove(const char *name)
{
return windows_named_sync::remove(name);
}
inline bool winapi_named_semaphore::remove(const wchar_t *name)
{
return windows_named_sync::remove(name);
}

View File

@@ -42,6 +42,7 @@ class windows_named_sync_interface
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 bool open(create_enum_t creation_type, const wchar_t *id_name) = 0;
virtual void close() = 0;
virtual ~windows_named_sync_interface() = 0;
};
@@ -60,10 +61,12 @@ class windows_named_sync
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);
template <class CharT>
void open_or_create(create_enum_t creation_type, const CharT *name, const permissions &perm, windows_named_sync_interface &sync_interface);
void close(windows_named_sync_interface &sync_interface);
static bool remove(const char *name);
static bool remove(const wchar_t *name);
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
@@ -79,11 +82,10 @@ inline windows_named_sync::windows_named_sync()
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)){
(m_file_hnd, winapi::lockfile_exclusive_lock, 0, 1, 0, &overlapped)){
if(winapi::set_file_pointer(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;
@@ -93,19 +95,21 @@ inline void windows_named_sync::close(windows_named_sync_interface &sync_interfa
}
}
sync_interface.close();
//close_handle unlocks the lock
if(m_file_hnd != winapi::invalid_handle_value){
winapi::close_handle(m_file_hnd);
m_file_hnd = winapi::invalid_handle_value;
}
}
template <class CharT>
inline void windows_named_sync::open_or_create
( create_enum_t creation_type
, const char *name
, const CharT *name
, const permissions &perm
, windows_named_sync_interface &sync_interface)
{
std::string aux_str(name);
std::basic_string<CharT> 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
@@ -130,7 +134,7 @@ inline void windows_named_sync::open_or_create
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)){
(m_file_hnd, winapi::lockfile_exclusive_lock, 0, 1, 0, &overlapped)){
__int64 filesize = 0;
//Obtain the unique id to open the native semaphore.
//If file size was created
@@ -162,7 +166,7 @@ inline void windows_named_sync::open_or_create
}
if(success){
//Now create a global semaphore name based on the unique id
char unique_id_name[sizeof(unique_id_val)*2+1];
CharT 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);
@@ -170,10 +174,11 @@ inline void windows_named_sync::open_or_create
}
//Obtain OS error in case something has failed
err = system_error_code();
if(!success)
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)){
if(!winapi::unlock_file_ex(m_file_hnd, 0, 1, 0, &overlapped)){
err = system_error_code();
}
}
@@ -199,15 +204,28 @@ inline void windows_named_sync::open_or_create
inline bool windows_named_sync::remove(const char *name)
{
try{
BOOST_TRY{
//Make sure a temporary path is created for shared memory
std::string semfile;
ipcdetail::shared_filepath(name, semfile);
return winapi::unlink_file(semfile.c_str());
}
catch(...){
BOOST_CATCH(...){
return false;
} BOOST_CATCH_END
}
inline bool windows_named_sync::remove(const wchar_t *name)
{
BOOST_TRY{
//Make sure a temporary path is created for shared memory
std::wstring semfile;
ipcdetail::shared_filepath(name, semfile);
return winapi::unlink_file(semfile.c_str());
}
BOOST_CATCH(...){
return false;
} BOOST_CATCH_END
}
} //namespace ipcdetail {

View File

@@ -28,13 +28,13 @@ namespace interprocess {
namespace ipcdetail {
//Windows mutex is already recursive
class windows_recursive_mutex
: public windows_mutex
class winapi_recursive_mutex
: public winapi_mutex
{
windows_recursive_mutex(const windows_recursive_mutex &);
windows_recursive_mutex &operator=(const windows_recursive_mutex &);
winapi_recursive_mutex(const winapi_recursive_mutex &);
winapi_recursive_mutex &operator=(const winapi_recursive_mutex &);
public:
windows_recursive_mutex() : windows_mutex() {}
winapi_recursive_mutex() : winapi_mutex() {}
};
} //namespace ipcdetail {

View File

@@ -21,7 +21,6 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
#include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#include <boost/interprocess/sync/windows/sync_utils.hpp>
@@ -34,80 +33,83 @@ namespace boost {
namespace interprocess {
namespace ipcdetail {
class windows_semaphore
class winapi_semaphore
{
windows_semaphore(const windows_semaphore &);
windows_semaphore &operator=(const windows_semaphore &);
winapi_semaphore(const winapi_semaphore &);
winapi_semaphore &operator=(const winapi_semaphore &);
public:
windows_semaphore(unsigned int initialCount);
~windows_semaphore();
winapi_semaphore(unsigned int initialCount);
~winapi_semaphore();
void post(long release_count = 1);
void post(unsigned int release_count = 1);
void wait();
bool try_wait();
bool timed_wait(const boost::posix_time::ptime &abs_time);
template<class TimePoint> bool timed_wait(const TimePoint &abs_time);
private:
const sync_id id_;
const unsigned initial_count_;
};
inline windows_semaphore::windows_semaphore(unsigned int initialCount)
: id_(this)
inline winapi_semaphore::winapi_semaphore(unsigned int initialCount)
: id_(), initial_count_(initialCount)
{
sync_handles &handles =
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);
handles.obtain_semaphore(this->id_, this, initialCount, &open_or_created);
//The semaphore must be created, never opened
BOOST_ASSERT(open_or_created);
BOOST_ASSERT(open_or_created && winapi::get_last_error() != winapi::error_already_exists);
(void)open_or_created;
}
inline windows_semaphore::~windows_semaphore()
inline winapi_semaphore::~winapi_semaphore()
{
sync_handles &handles =
windows_intermodule_singleton<sync_handles>::get();
handles.destroy_handle(this->id_);
handles.destroy_handle(this->id_, this);
}
inline void windows_semaphore::wait(void)
inline void winapi_semaphore::wait()
{
sync_handles &handles =
windows_intermodule_singleton<sync_handles>::get();
//This can throw
winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, this, initial_count_));
sem.wait();
}
inline bool windows_semaphore::try_wait(void)
inline bool winapi_semaphore::try_wait()
{
sync_handles &handles =
windows_intermodule_singleton<sync_handles>::get();
//This can throw
winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, this, initial_count_));
return sem.try_wait();
}
inline bool windows_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
template<class TimePoint>
inline bool winapi_semaphore::timed_wait(const TimePoint &abs_time)
{
sync_handles &handles =
windows_intermodule_singleton<sync_handles>::get();
//This can throw
winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, this, initial_count_));
return sem.timed_wait(abs_time);
}
inline void windows_semaphore::post(long release_count)
inline void winapi_semaphore::post(unsigned release_count)
{
sync_handles &handles =
windows_intermodule_singleton<sync_handles>::get();
winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
sem.post(release_count);
winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, this, initial_count_));
sem.post(static_cast<long>(release_count));
}
} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {

View File

@@ -30,11 +30,10 @@
//Shield against external warnings
#include <boost/interprocess/detail/config_external_begin.hpp>
#include <boost/unordered/unordered_map.hpp>
#include <boost/unordered/unordered_map.hpp>
#include <boost/interprocess/detail/config_external_end.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/map.hpp>
#include <cstddef>
namespace boost {
@@ -63,16 +62,36 @@ inline bool bytes_to_str(const void *mem, const std::size_t mem_length, char *ou
return true;
}
inline bool bytes_to_str(const void *mem, const std::size_t mem_length, wchar_t *out_str, std::size_t &out_length)
{
const std::size_t need_mem = mem_length*2+1;
if(out_length < need_mem){
out_length = need_mem;
return false;
}
const wchar_t Characters [] =
{ L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7'
, L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
std::size_t char_counter = 0;
const char *buf = (const char *)mem;
for(std::size_t i = 0; i != mem_length; ++i){
out_str[char_counter++] = Characters[(buf[i]&0xF0)>>4];
out_str[char_counter++] = Characters[(buf[i]&0x0F)];
}
out_str[char_counter] = 0;
return true;
}
class sync_id
{
public:
typedef __int64 internal_type;
sync_id(const void *map_addr)
: map_addr_(map_addr)
sync_id()
{ winapi::query_performance_counter(&rand_); }
explicit sync_id(internal_type val, const void *map_addr)
: map_addr_(map_addr)
explicit sync_id(internal_type val)
{ rand_ = val; }
const internal_type &internal_pod() const
@@ -81,18 +100,14 @@ class sync_id
internal_type &internal_pod()
{ return rand_; }
const void *map_address() const
{ return map_addr_; }
friend std::size_t hash_value(const sync_id &m)
{ return boost::hash_value(m.rand_); }
friend bool operator==(const sync_id &l, const sync_id &r)
{ return l.rand_ == r.rand_ && l.map_addr_ == r.map_addr_; }
{ return l.rand_ == r.rand_; }
private:
internal_type rand_;
const void * const map_addr_;
};
class sync_handles
@@ -101,19 +116,15 @@ class sync_handles
enum type { MUTEX, SEMAPHORE };
private:
struct address_less
{
bool operator()(sync_id const * const l, sync_id const * const r) const
{ return l->map_address() < r->map_address(); }
};
//key: id -> mapped: HANDLE. Hash map to allow efficient sync operations
typedef boost::unordered_map<sync_id, void*> umap_type;
typedef boost::container::map<const sync_id*, umap_type::iterator, address_less> map_type;
//key: ordered address of the sync type -> iterator from umap_type. Ordered map to allow closing handles when unmapping
typedef boost::container::flat_map<const void*, umap_type::iterator> 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";
@@ -129,7 +140,7 @@ class sync_handles
void throw_if_error(void *hnd_val)
{
if(!hnd_val){
error_info err(winapi::get_last_error());
error_info err(static_cast<int>(winapi::get_last_error()));
throw interprocess_exception(err);
}
}
@@ -161,41 +172,57 @@ class sync_handles
}
public:
void *obtain_mutex(const sync_id &id, bool *popen_created = 0)
sync_handles()
: num_handles_()
{}
~sync_handles()
{
BOOST_ASSERT(num_handles_ == 0); //Sanity check that handle we don't leak handles
}
void *obtain_mutex(const sync_id &id, const void *mapping_address, bool *popen_created = 0)
{
umap_type::value_type v(id, (void*)0);
scoped_lock<spin_mutex> lock(mtx_);
umap_type::iterator it = umap_.insert(v).first;
void *&hnd_val = it->second;
if(!hnd_val){
map_[&it->first] = it;
BOOST_ASSERT(map_.find(mapping_address) == map_.end());
map_[mapping_address] = it;
hnd_val = open_or_create_mutex(id);
if(popen_created) *popen_created = true;
++num_handles_;
}
else if(popen_created){
BOOST_ASSERT(map_.find(mapping_address) != map_.end());
*popen_created = false;
}
return hnd_val;
}
void *obtain_semaphore(const sync_id &id, unsigned int initial_count, bool *popen_created = 0)
void *obtain_semaphore(const sync_id &id, const void *mapping_address, unsigned int initial_count, bool *popen_created = 0)
{
umap_type::value_type v(id, (void*)0);
scoped_lock<spin_mutex> lock(mtx_);
umap_type::iterator it = umap_.insert(v).first;
void *&hnd_val = it->second;
if(!hnd_val){
map_[&it->first] = it;
BOOST_ASSERT(map_.find(mapping_address) == map_.end());
map_[mapping_address] = it;
hnd_val = open_or_create_semaphore(id, initial_count);
if(popen_created) *popen_created = true;
++num_handles_;
}
else if(popen_created){
BOOST_ASSERT(map_.find(mapping_address) != map_.end());
*popen_created = false;
}
return hnd_val;
}
void destroy_handle(const sync_id &id)
void destroy_handle(const sync_id &id, const void *mapping_address)
{
scoped_lock<spin_mutex> lock(mtx_);
umap_type::iterator it = umap_.find(id);
@@ -203,31 +230,39 @@ class sync_handles
if(it != itend){
winapi::close_handle(it->second);
const map_type::key_type &k = &it->first;
map_.erase(k);
--num_handles_;
std::size_t i = map_.erase(mapping_address);
(void)i;
BOOST_ASSERT(i == 1); //The entry should be there
umap_.erase(it);
}
}
void destroy_syncs_in_range(const void *addr, std::size_t size)
{
const sync_id low_id(addr);
const sync_id hig_id(static_cast<const char*>(addr)+size);
const void *low_id(addr);
const void *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 * const hnd = umap_[*itlow->first];
winapi::close_handle(hnd);
umap_.erase(*itlow->first);
itlow = map_.erase(itlow);
map_type::iterator itlow(map_.lower_bound(low_id)),
ithig(map_.lower_bound(hig_id)),
it(itlow);
for (; it != ithig; ++it){
umap_type::iterator uit = it->second;
void * const hnd = uit->second;
umap_.erase(uit);
int ret = winapi::close_handle(hnd);
--num_handles_;
BOOST_ASSERT(ret != 0); (void)ret; //Sanity check that handle was ok
}
map_.erase(itlow, ithig);
}
private:
spin_mutex mtx_;
umap_type umap_;
map_type map_;
std::size_t num_handles_;
};

View File

@@ -24,7 +24,6 @@
#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/sync/windows/winapi_wrapper_common.hpp>
#include <boost/interprocess/errors.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -57,7 +56,8 @@ class winapi_mutex_functions
bool try_lock()
{ return winapi_wrapper_try_wait_for_single_object(m_mtx_hnd); }
bool timed_lock(const boost::posix_time::ptime &abs_time)
template<class TimePoint>
bool timed_lock(const TimePoint &abs_time)
{ return winapi_wrapper_timed_wait_for_single_object(m_mtx_hnd, abs_time); }
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
@@ -98,7 +98,8 @@ class winapi_mutex_wrapper
void *handle() const
{ return m_mtx_hnd; }
bool open_or_create(const char *name, const permissions &perm)
template<class CharT>
bool open_or_create(const CharT *name, const permissions &perm)
{
if(m_mtx_hnd == 0){
m_mtx_hnd = winapi::open_or_create_mutex

View File

@@ -24,7 +24,6 @@
#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/sync/windows/winapi_wrapper_common.hpp>
#include <boost/interprocess/errors.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -60,7 +59,8 @@ class winapi_semaphore_functions
bool try_wait()
{ return winapi_wrapper_try_wait_for_single_object(m_sem_hnd); }
bool timed_wait(const boost::posix_time::ptime &abs_time)
template<class TimePoint>
bool timed_wait(const TimePoint &abs_time)
{ return winapi_wrapper_timed_wait_for_single_object(m_sem_hnd, abs_time); }
long value() const
@@ -115,7 +115,8 @@ class winapi_semaphore_wrapper
void *handle() const
{ return m_sem_hnd; }
bool open_or_create( const char *name
template <class CharT>
bool open_or_create( const CharT *name
, long sem_count
, long max_count
, const permissions &perm

View File

@@ -22,41 +22,18 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/errors.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/timed_utils.hpp>
#include <limits>
namespace boost {
namespace interprocess {
namespace ipcdetail {
inline bool winapi_wrapper_timed_wait_for_single_object(void *handle, const boost::posix_time::ptime &abs_time);
inline void winapi_wrapper_wait_for_single_object(void *handle)
inline bool do_winapi_wait(void *handle, unsigned long dwMilliseconds)
{
winapi_wrapper_timed_wait_for_single_object(handle, boost::posix_time::pos_infin);
}
inline bool winapi_wrapper_try_wait_for_single_object(void *handle)
{
return winapi_wrapper_timed_wait_for_single_object(handle, boost::posix_time::min_date_time);
}
inline bool winapi_wrapper_timed_wait_for_single_object(void *handle, const boost::posix_time::ptime &abs_time)
{
const boost::posix_time::ptime cur_time = microsec_clock::universal_time();
//Windows uses relative wait times so check for negative waits
//and implement as 0 wait to allow try-semantics as POSIX mandates.
unsigned long time = 0u;
if (abs_time == boost::posix_time::pos_infin){
time = winapi::infinite_time;
}
else if(abs_time > cur_time){
time = (abs_time - cur_time).total_milliseconds();
}
unsigned long ret = winapi::wait_for_single_object(handle, time);
unsigned long ret = winapi::wait_for_single_object(handle, dwMilliseconds);
if(ret == winapi::wait_object_0){
return true;
}
@@ -73,6 +50,34 @@ inline bool winapi_wrapper_timed_wait_for_single_object(void *handle, const boos
}
}
template<class TimePoint>
inline bool winapi_wrapper_timed_wait_for_single_object(void *handle, const TimePoint &abs_time)
{
//Windows uses relative wait times so check for negative waits
//and implement as 0 wait to allow try-semantics as POSIX mandates.
unsigned long time_ms = 0u;
if (ipcdetail::is_pos_infinity(abs_time)){
time_ms = winapi::infinite_time;
}
else {
const TimePoint cur_time = microsec_clock<TimePoint>::universal_time();
if(abs_time > cur_time){
time_ms = static_cast<unsigned long>(duration_to_milliseconds(abs_time - cur_time));
}
}
return do_winapi_wait(handle, time_ms);
}
inline void winapi_wrapper_wait_for_single_object(void *handle)
{
(void)do_winapi_wait(handle, winapi::infinite_time);
}
inline bool winapi_wrapper_try_wait_for_single_object(void *handle)
{
return do_winapi_wait(handle, 0u);
}
} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {