mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-02 21:47:47 +00:00
Added thirdparty: boost library
This commit is contained in:
+146
@@ -0,0 +1,146 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_CONDITION_HPP
|
||||
#define BOOST_INTERPROCESS_DETAIL_WINDOWS_CONDITION_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.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>
|
||||
#include <boost/interprocess/sync/windows/semaphore.hpp>
|
||||
#include <boost/interprocess/sync/windows/mutex.hpp>
|
||||
#include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail {
|
||||
|
||||
class winapi_condition
|
||||
{
|
||||
winapi_condition(const winapi_condition &);
|
||||
winapi_condition &operator=(const winapi_condition &);
|
||||
|
||||
public:
|
||||
winapi_condition()
|
||||
: m_condition_data()
|
||||
{}
|
||||
|
||||
~winapi_condition()
|
||||
{
|
||||
//Notify all waiting threads
|
||||
//to allow POSIX semantics on condition destruction
|
||||
this->notify_all();
|
||||
}
|
||||
|
||||
void notify_one()
|
||||
{ m_condition_data.notify_one(); }
|
||||
|
||||
void notify_all()
|
||||
{ m_condition_data.notify_all(); }
|
||||
|
||||
template <typename L>
|
||||
void wait(L& lock)
|
||||
{ m_condition_data.wait(lock); }
|
||||
|
||||
template <typename L, typename Pr>
|
||||
void wait(L& lock, Pr pred)
|
||||
{ m_condition_data.wait(lock, pred); }
|
||||
|
||||
|
||||
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 unsigned int integer_type;
|
||||
typedef winapi_semaphore semaphore_type;
|
||||
typedef winapi_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; }
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
} //namespace ipcdetail
|
||||
} //namespace interprocess
|
||||
} //namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_DETAIL_WINDOWS_CONDITION_HPP
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_MUTEX_HPP
|
||||
#define BOOST_INTERPROCESS_DETAIL_WINDOWS_MUTEX_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/detail/win32_api.hpp>
|
||||
#include <boost/interprocess/detail/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>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail {
|
||||
|
||||
class winapi_mutex
|
||||
{
|
||||
winapi_mutex(const winapi_mutex &);
|
||||
winapi_mutex &operator=(const winapi_mutex &);
|
||||
public:
|
||||
|
||||
winapi_mutex();
|
||||
~winapi_mutex();
|
||||
|
||||
void lock();
|
||||
bool try_lock();
|
||||
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(){};
|
||||
|
||||
private:
|
||||
const sync_id id_;
|
||||
};
|
||||
|
||||
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_, 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 winapi_mutex::~winapi_mutex()
|
||||
{
|
||||
sync_handles &handles =
|
||||
windows_intermodule_singleton<sync_handles>::get();
|
||||
handles.destroy_handle(this->id_, this);
|
||||
}
|
||||
|
||||
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_, this));
|
||||
mut.lock();
|
||||
}
|
||||
|
||||
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_, this));
|
||||
return mut.try_lock();
|
||||
}
|
||||
|
||||
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_, this));
|
||||
return mut.timed_lock(abs_time);
|
||||
}
|
||||
|
||||
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_, this));
|
||||
return mut.unlock();
|
||||
}
|
||||
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_DETAIL_WINDOWS_MUTEX_HPP
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#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 winapi_named_condition_any winapi_named_condition;
|
||||
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_HPP
|
||||
+336
@@ -0,0 +1,336 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
|
||||
#define BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#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/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 {
|
||||
|
||||
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
|
||||
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:
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
void notify_one()
|
||||
{ m_condition_data.notify_one(); }
|
||||
|
||||
void notify_all()
|
||||
{ m_condition_data.notify_all(); }
|
||||
|
||||
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>
|
||||
void wait(L& lock)
|
||||
{ m_condition_data.wait(lock); }
|
||||
|
||||
template <typename L, typename Pr>
|
||||
void wait(L& lock, Pr pred)
|
||||
{ m_condition_data.wait(lock, pred); }
|
||||
|
||||
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:
|
||||
|
||||
void dont_close_on_destruction()
|
||||
{}
|
||||
|
||||
friend class interprocess_tester;
|
||||
|
||||
struct condition_data
|
||||
{
|
||||
typedef boost::int32_t integer_type;
|
||||
typedef winapi_semaphore_wrapper semaphore_type;
|
||||
typedef winapi_mutex_wrapper mutex_type;
|
||||
|
||||
integer_type &get_nwaiters_blocked()
|
||||
{ return m_nwaiters_blocked; }
|
||||
|
||||
integer_type &get_nwaiters_gone()
|
||||
{ return m_nwaiters_gone; }
|
||||
|
||||
integer_type &get_nwaiters_to_unblock()
|
||||
{ return m_nwaiters_to_unblock; }
|
||||
|
||||
semaphore_type &get_sem_block_queue()
|
||||
{ return m_sem_block_queue; }
|
||||
|
||||
semaphore_type &get_sem_block_lock()
|
||||
{ return m_sem_block_lock; }
|
||||
|
||||
mutex_type &get_mtx_unblock_lock()
|
||||
{ return m_mtx_unblock_lock; }
|
||||
|
||||
integer_type m_nwaiters_blocked;
|
||||
integer_type m_nwaiters_gone;
|
||||
integer_type m_nwaiters_to_unblock;
|
||||
winapi_semaphore_wrapper m_sem_block_queue;
|
||||
winapi_semaphore_wrapper m_sem_block_lock;
|
||||
winapi_mutex_wrapper m_mtx_unblock_lock;
|
||||
};
|
||||
|
||||
|
||||
class named_cond_callbacks : public windows_named_sync_interface
|
||||
{
|
||||
typedef __int64 sem_count_t;
|
||||
mutable sem_count_t sem_counts [2];
|
||||
|
||||
public:
|
||||
named_cond_callbacks(condition_data &cond_data)
|
||||
: m_condition_data(cond_data)
|
||||
{}
|
||||
|
||||
virtual std::size_t get_data_size() const BOOST_OVERRIDE
|
||||
{ return sizeof(sem_counts); }
|
||||
|
||||
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() BOOST_OVERRIDE
|
||||
{
|
||||
sem_counts[0] = 0;
|
||||
sem_counts[1] = 1;
|
||||
return &sem_counts;
|
||||
}
|
||||
|
||||
virtual void *buffer_to_store_init_data_from_file() BOOST_OVERRIDE
|
||||
{ return &sem_counts; }
|
||||
|
||||
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;
|
||||
|
||||
//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::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 += str_t::bq();
|
||||
winapi_semaphore_wrapper sem_block_queue;
|
||||
bool created;
|
||||
if(!sem_block_queue.open_or_create
|
||||
(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 += str_t::bl();
|
||||
winapi_semaphore_wrapper sem_block_lock;
|
||||
if(!sem_block_lock.open_or_create
|
||||
(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 += str_t::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;
|
||||
}
|
||||
|
||||
condition_data &m_condition_data;
|
||||
};
|
||||
|
||||
windows_named_sync m_named_sync;
|
||||
ipcdetail::condition_8a_wrapper<condition_data> m_condition_data;
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_ANY_HPP
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# 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/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 winapi_named_mutex
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
//Non-copyable
|
||||
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:
|
||||
winapi_named_mutex(create_only_t, const char *name, const permissions &perm = permissions());
|
||||
|
||||
winapi_named_mutex(open_or_create_t, const char *name, const permissions &perm = permissions());
|
||||
|
||||
winapi_named_mutex(open_only_t, const char *name);
|
||||
|
||||
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();
|
||||
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;
|
||||
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 BOOST_OVERRIDE
|
||||
{ return 0u; }
|
||||
|
||||
virtual const void *buffer_with_init_data_to_file() BOOST_OVERRIDE
|
||||
{ return 0; }
|
||||
|
||||
virtual const void *buffer_with_final_data_to_file() BOOST_OVERRIDE
|
||||
{ return 0; }
|
||||
|
||||
virtual void *buffer_to_store_init_data_from_file() BOOST_OVERRIDE
|
||||
{ return 0; }
|
||||
|
||||
virtual bool open(create_enum_t, const char *id_name) BOOST_OVERRIDE
|
||||
{
|
||||
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 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() BOOST_OVERRIDE
|
||||
{}
|
||||
|
||||
private:
|
||||
winapi_mutex_wrapper& m_mtx_wrapper;
|
||||
};
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
inline winapi_named_mutex::~winapi_named_mutex()
|
||||
{
|
||||
named_mut_callbacks callbacks(m_mtx_wrapper);
|
||||
m_named_sync.close(callbacks);
|
||||
}
|
||||
|
||||
inline void winapi_named_mutex::dont_close_on_destruction()
|
||||
{}
|
||||
|
||||
inline winapi_named_mutex::winapi_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 winapi_named_mutex::winapi_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 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 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 winapi_named_mutex::lock()
|
||||
{
|
||||
m_mtx_wrapper.lock();
|
||||
}
|
||||
|
||||
inline bool winapi_named_mutex::try_lock()
|
||||
{
|
||||
return m_mtx_wrapper.try_lock();
|
||||
}
|
||||
|
||||
template<class TimePoint>
|
||||
inline bool winapi_named_mutex::timed_lock(const TimePoint &abs_time)
|
||||
{
|
||||
return m_mtx_wrapper.timed_lock(abs_time);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_MUTEX_HPP
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# 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 winapi_named_recursive_mutex
|
||||
//Windows mutexes based on CreateMutex are already recursive...
|
||||
: public winapi_named_mutex
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
//Non-copyable
|
||||
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:
|
||||
winapi_named_recursive_mutex(create_only_t, const char *name, const permissions &perm = permissions())
|
||||
: winapi_named_mutex(create_only_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)
|
||||
{}
|
||||
|
||||
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)
|
||||
{}
|
||||
};
|
||||
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_WINDOWS_RECURSIVE_NAMED_MUTEX_HPP
|
||||
+230
@@ -0,0 +1,230 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# 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/sync/windows/named_sync.hpp>
|
||||
#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail {
|
||||
|
||||
|
||||
|
||||
class winapi_named_semaphore
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
//Non-copyable
|
||||
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:
|
||||
winapi_named_semaphore(create_only_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());
|
||||
|
||||
winapi_named_semaphore(open_only_t, const char *name);
|
||||
|
||||
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();
|
||||
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:
|
||||
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 BOOST_OVERRIDE
|
||||
{ return sizeof(sem_count_t); }
|
||||
|
||||
virtual const void *buffer_with_final_data_to_file() BOOST_OVERRIDE
|
||||
{ return &m_sem_count; }
|
||||
|
||||
virtual const void *buffer_with_init_data_to_file() BOOST_OVERRIDE
|
||||
{ return &m_sem_count; }
|
||||
|
||||
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) BOOST_OVERRIDE
|
||||
{
|
||||
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 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() BOOST_OVERRIDE
|
||||
{}
|
||||
|
||||
private:
|
||||
winapi_semaphore_wrapper& m_sem_wrapper;
|
||||
sem_count_t m_sem_count;
|
||||
};
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
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 winapi_named_semaphore::dont_close_on_destruction()
|
||||
{}
|
||||
|
||||
inline winapi_named_semaphore::winapi_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 winapi_named_semaphore::winapi_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 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 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 winapi_named_semaphore::wait()
|
||||
{
|
||||
m_sem_wrapper.wait();
|
||||
}
|
||||
|
||||
inline bool winapi_named_semaphore::try_wait()
|
||||
{
|
||||
return m_sem_wrapper.try_wait();
|
||||
}
|
||||
|
||||
template<class TimePoint>
|
||||
inline bool winapi_named_semaphore::timed_wait(const TimePoint &abs_time)
|
||||
{
|
||||
return m_sem_wrapper.timed_wait(abs_time);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_SEMAPHORE_HPP
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# 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/shared_dir_helpers.hpp>
|
||||
#include <boost/interprocess/sync/windows/sync_utils.hpp>
|
||||
#include <boost/interprocess/errors.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <string>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
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 bool open(create_enum_t creation_type, const wchar_t *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
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
//Non-copyable
|
||||
windows_named_sync(const windows_named_sync &);
|
||||
windows_named_sync &operator=(const windows_named_sync &);
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
windows_named_sync();
|
||||
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:
|
||||
void *m_file_hnd;
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
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();
|
||||
winapi::interprocess_overlapped overlapped;
|
||||
if(winapi::lock_file_ex
|
||||
(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;
|
||||
if(winapi::write_file(m_file_hnd, buf, buflen, &written_or_read, 0)){
|
||||
//...
|
||||
}
|
||||
}
|
||||
}
|
||||
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 CharT *name
|
||||
, const permissions &perm
|
||||
, windows_named_sync_interface &sync_interface)
|
||||
{
|
||||
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
|
||||
{
|
||||
create_shared_dir_cleaning_old_and_get_filepath(name, aux_str);
|
||||
//Create a file with required permissions.
|
||||
m_file_hnd = winapi::create_file
|
||||
( aux_str.c_str()
|
||||
, 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, 1, 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);
|
||||
BOOST_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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
//Obtain OS error in case something has failed
|
||||
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, 1, 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)
|
||||
{
|
||||
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());
|
||||
}
|
||||
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 {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_RECURSIVE_MUTEX_HPP
|
||||
#define BOOST_INTERPROCESS_DETAIL_WINDOWS_RECURSIVE_MUTEX_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/sync/windows/mutex.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail {
|
||||
|
||||
//Windows mutex is already recursive
|
||||
class winapi_recursive_mutex
|
||||
: public winapi_mutex
|
||||
{
|
||||
winapi_recursive_mutex(const winapi_recursive_mutex &);
|
||||
winapi_recursive_mutex &operator=(const winapi_recursive_mutex &);
|
||||
public:
|
||||
winapi_recursive_mutex() : winapi_mutex() {}
|
||||
};
|
||||
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_DETAIL_WINDOWS_RECURSIVE_MUTEX_HPP
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_WINDOWS_SEMAPHORE_HPP
|
||||
#define BOOST_INTERPROCESS_DETAIL_WINDOWS_SEMAPHORE_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/detail/win32_api.hpp>
|
||||
#include <boost/interprocess/detail/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>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail {
|
||||
|
||||
class winapi_semaphore
|
||||
{
|
||||
winapi_semaphore(const winapi_semaphore &);
|
||||
winapi_semaphore &operator=(const winapi_semaphore &);
|
||||
public:
|
||||
|
||||
winapi_semaphore(unsigned int initialCount);
|
||||
~winapi_semaphore();
|
||||
|
||||
void post(unsigned int release_count = 1);
|
||||
void wait();
|
||||
bool try_wait();
|
||||
template<class TimePoint> bool timed_wait(const TimePoint &abs_time);
|
||||
|
||||
private:
|
||||
const sync_id id_;
|
||||
const unsigned initial_count_;
|
||||
};
|
||||
|
||||
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_, 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 winapi_semaphore::~winapi_semaphore()
|
||||
{
|
||||
sync_handles &handles =
|
||||
windows_intermodule_singleton<sync_handles>::get();
|
||||
handles.destroy_handle(this->id_, this);
|
||||
}
|
||||
|
||||
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_, this, initial_count_));
|
||||
sem.wait();
|
||||
}
|
||||
|
||||
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_, this, initial_count_));
|
||||
return sem.try_wait();
|
||||
}
|
||||
|
||||
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_, this, initial_count_));
|
||||
return sem.timed_wait(abs_time);
|
||||
}
|
||||
|
||||
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_, this, initial_count_));
|
||||
sem.post(static_cast<long>(release_count));
|
||||
}
|
||||
|
||||
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_DETAIL_WINDOWS_SEMAPHORE_HPP
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_SYNC_UTILS_HPP
|
||||
#define BOOST_INTERPROCESS_DETAIL_SYNC_UTILS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/detail/win32_api.hpp>
|
||||
#include <boost/interprocess/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>
|
||||
|
||||
//Shield against external warnings
|
||||
#include <boost/interprocess/detail/config_external_begin.hpp>
|
||||
#include <boost/unordered/unordered_map.hpp>
|
||||
#include <boost/interprocess/detail/config_external_end.hpp>
|
||||
#include <boost/container/flat_map.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail {
|
||||
|
||||
inline bool bytes_to_str(const void *mem, const std::size_t mem_length, char *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 char Characters [] =
|
||||
{ '0', '1', '2', '3', '4', '5', '6', '7'
|
||||
, '8', '9', 'A', 'B', 'C', 'D', 'E', '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;
|
||||
}
|
||||
|
||||
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()
|
||||
{ winapi::query_performance_counter(&rand_); }
|
||||
|
||||
explicit sync_id(internal_type val)
|
||||
{ rand_ = val; }
|
||||
|
||||
const internal_type &internal_pod() const
|
||||
{ return rand_; }
|
||||
|
||||
internal_type &internal_pod()
|
||||
{ return rand_; }
|
||||
|
||||
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_; }
|
||||
|
||||
private:
|
||||
internal_type rand_;
|
||||
};
|
||||
|
||||
class sync_handles
|
||||
{
|
||||
public:
|
||||
enum type { MUTEX, SEMAPHORE };
|
||||
|
||||
private:
|
||||
|
||||
//key: id -> mapped: HANDLE. Hash map to allow efficient sync operations
|
||||
typedef boost::unordered_map<sync_id, void*> umap_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";
|
||||
std::size_t i = 0;
|
||||
do{
|
||||
name[i] = n[i];
|
||||
++i;
|
||||
} while(n[i]);
|
||||
std::size_t len = sizeof(NameBuf) - LengthOfGlobal;
|
||||
bytes_to_str(&id.internal_pod(), sizeof(id.internal_pod()), &name[LengthOfGlobal], len);
|
||||
}
|
||||
|
||||
void throw_if_error(void *hnd_val)
|
||||
{
|
||||
if(!hnd_val){
|
||||
error_info err(static_cast<int>(winapi::get_last_error()));
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
}
|
||||
|
||||
void* open_or_create_semaphore(const sync_id &id, unsigned int initial_count)
|
||||
{
|
||||
NameBuf name;
|
||||
fill_name(name, id);
|
||||
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);
|
||||
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:
|
||||
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){
|
||||
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, 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){
|
||||
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, const void *mapping_address)
|
||||
{
|
||||
scoped_lock<spin_mutex> lock(mtx_);
|
||||
umap_type::iterator it = umap_.find(id);
|
||||
umap_type::iterator itend = umap_.end();
|
||||
|
||||
if(it != itend){
|
||||
winapi::close_handle(it->second);
|
||||
--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 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)),
|
||||
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_;
|
||||
};
|
||||
|
||||
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_DETAIL_SYNC_UTILS_HPP
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# 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/sync/windows/winapi_wrapper_common.hpp>
|
||||
#include <boost/interprocess/errors.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail {
|
||||
|
||||
class winapi_mutex_functions
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
//Non-copyable
|
||||
winapi_mutex_functions(const winapi_mutex_functions &);
|
||||
winapi_mutex_functions &operator=(const winapi_mutex_functions &);
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
winapi_mutex_functions(void *mtx_hnd)
|
||||
: m_mtx_hnd(mtx_hnd)
|
||||
{}
|
||||
|
||||
void unlock()
|
||||
{ winapi::release_mutex(m_mtx_hnd); }
|
||||
|
||||
void lock()
|
||||
{ return winapi_wrapper_wait_for_single_object(m_mtx_hnd); }
|
||||
|
||||
bool try_lock()
|
||||
{ return winapi_wrapper_try_wait_for_single_object(m_mtx_hnd); }
|
||||
|
||||
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)
|
||||
protected:
|
||||
void *m_mtx_hnd;
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
//Swappable mutex wrapper
|
||||
class winapi_mutex_wrapper
|
||||
: public winapi_mutex_functions
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
//Non-copyable
|
||||
winapi_mutex_wrapper(const winapi_mutex_wrapper &);
|
||||
winapi_mutex_wrapper &operator=(const winapi_mutex_wrapper &);
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
//Note that Windows API does not return winapi::invalid_handle_value
|
||||
//when failing to create/open a mutex, but a nullptr
|
||||
|
||||
public:
|
||||
winapi_mutex_wrapper(void *mtx_hnd = 0)
|
||||
: winapi_mutex_functions(mtx_hnd)
|
||||
{}
|
||||
|
||||
~winapi_mutex_wrapper()
|
||||
{ this->close(); }
|
||||
|
||||
void *release()
|
||||
{
|
||||
void *hnd = m_mtx_hnd;
|
||||
m_mtx_hnd = 0;
|
||||
return hnd;
|
||||
}
|
||||
|
||||
void *handle() const
|
||||
{ return m_mtx_hnd; }
|
||||
|
||||
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
|
||||
( name
|
||||
, false
|
||||
, (winapi::interprocess_security_attributes*)perm.get_permissions()
|
||||
);
|
||||
return m_mtx_hnd != 0;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
if(m_mtx_hnd != 0){
|
||||
winapi::close_handle(m_mtx_hnd);
|
||||
m_mtx_hnd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# 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/sync/windows/winapi_wrapper_common.hpp>
|
||||
#include <boost/interprocess/errors.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail {
|
||||
|
||||
class winapi_semaphore_functions
|
||||
{
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
|
||||
//Non-copyable
|
||||
winapi_semaphore_functions(const winapi_semaphore_functions &);
|
||||
winapi_semaphore_functions &operator=(const winapi_semaphore_functions &);
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
|
||||
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()
|
||||
{ return winapi_wrapper_wait_for_single_object(m_sem_hnd); }
|
||||
|
||||
bool try_wait()
|
||||
{ return winapi_wrapper_try_wait_for_single_object(m_sem_hnd); }
|
||||
|
||||
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
|
||||
{
|
||||
long l_count, l_limit;
|
||||
if(!winapi::get_semaphore_info(m_sem_hnd, l_count, l_limit))
|
||||
return 0;
|
||||
return l_count;
|
||||
}
|
||||
|
||||
long limit() const
|
||||
{
|
||||
long l_count, l_limit;
|
||||
if(!winapi::get_semaphore_info(m_sem_hnd, l_count, l_limit))
|
||||
return 0;
|
||||
return l_limit;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
||||
protected:
|
||||
void *m_sem_hnd;
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
|
||||
//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; }
|
||||
|
||||
template <class CharT>
|
||||
bool open_or_create( const CharT *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
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_WINAPI_WRAPPER_COMMON_HPP
|
||||
#define BOOST_INTERPROCESS_DETAIL_WINAPI_WRAPPER_COMMON_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/detail/win32_api.hpp>
|
||||
#include <boost/interprocess/errors.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/detail/timed_utils.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail {
|
||||
|
||||
inline bool do_winapi_wait(void *handle, unsigned long dwMilliseconds)
|
||||
{
|
||||
unsigned long ret = winapi::wait_for_single_object(handle, dwMilliseconds);
|
||||
if(ret == winapi::wait_object_0){
|
||||
return true;
|
||||
}
|
||||
else if(ret == winapi::wait_timeout){
|
||||
return false;
|
||||
}
|
||||
else if(ret == winapi::wait_abandoned){ //Special case for orphaned mutexes
|
||||
winapi::release_mutex(handle);
|
||||
throw interprocess_exception(owner_dead_error);
|
||||
}
|
||||
else{
|
||||
error_info err = system_error_code();
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_DETAIL_WINAPI_WRAPPER_COMMON_HPP
|
||||
Reference in New Issue
Block a user