summaryrefslogtreecommitdiff
path: root/boost/interprocess/sync/windows/sync_utils.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess/sync/windows/sync_utils.hpp')
-rw-r--r--boost/interprocess/sync/windows/sync_utils.hpp117
1 files changed, 84 insertions, 33 deletions
diff --git a/boost/interprocess/sync/windows/sync_utils.hpp b/boost/interprocess/sync/windows/sync_utils.hpp
index 89c4aeda0b..0281da1266 100644
--- a/boost/interprocess/sync/windows/sync_utils.hpp
+++ b/boost/interprocess/sync/windows/sync_utils.hpp
@@ -21,7 +21,10 @@
#include <boost/interprocess/sync/spin/mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
#include <boost/unordered/unordered_map.hpp>
+#include <boost/container/map.hpp>
#include <cstddef>
namespace boost {
@@ -32,6 +35,7 @@ inline bool bytes_to_str(const void *mem, const std::size_t mem_length, char *ou
{
const std::size_t need_mem = mem_length*2+1;
if(out_length < need_mem){
+ out_length = need_mem;
return false;
}
@@ -49,40 +53,57 @@ inline bool bytes_to_str(const void *mem, const std::size_t mem_length, char *ou
return true;
}
-struct sync_id
+class sync_id
{
- sync_id()
- { winapi::query_performance_counter(&rand); }
+ public:
+ typedef __int64 internal_type;
+ sync_id(const void *map_addr)
+ : map_addr_(map_addr)
+ { winapi::query_performance_counter(&rand_); }
+
+ explicit sync_id(internal_type val, const void *map_addr)
+ : map_addr_(map_addr)
+ { rand_ = val; }
+
+ const internal_type &internal_pod() const
+ { return rand_; }
- __int64 rand;
+ internal_type &internal_pod()
+ { return rand_; }
+
+ const void *map_addr() const
+ { return map_addr_; }
friend std::size_t hash_value(const sync_id &m)
- { return boost::hash_value(m.rand); }
+ { return boost::hash_value(m.rand_); }
friend bool operator==(const sync_id &l, const sync_id &r)
- { return l.rand == r.rand; }
-};
-/*
-#define BOOST_NO_LONG_LONG ss
+ { return l.rand_ == r.rand_ && l.map_addr_ == r.map_addr_; }
-#if defined(BOOST_NO_LONG_LONG)
+ private:
+ internal_type rand_;
+ const void * const map_addr_;
+};
-#error "defined(BOOST_NO_LONG_LONG)"
-#else
-#error "NOT defined(BOOST_NO_LONG_LONG)"
-#endif
-*/
class sync_handles
{
public:
enum type { MUTEX, SEMAPHORE };
private:
- typedef boost::unordered_map<sync_id, void*> map_type;
+ struct address_less
+ {
+ bool operator()(sync_id const * const l, sync_id const * const r) const
+ { return l->map_addr() < r->map_addr(); }
+ };
+
+ typedef boost::unordered_map<sync_id, void*> umap_type;
+ typedef boost::container::map<const sync_id*, umap_type::iterator, address_less> map_type;
static const std::size_t LengthOfGlobal = sizeof("Global\\boost.ipc")-1;
static const std::size_t StrSize = LengthOfGlobal + (sizeof(sync_id)*2+1);
typedef char NameBuf[StrSize];
+
void fill_name(NameBuf &name, const sync_id &id)
{
const char *n = "Global\\boost.ipc";
@@ -92,13 +113,12 @@ class sync_handles
++i;
} while(n[i]);
std::size_t len = sizeof(NameBuf) - LengthOfGlobal;
- bytes_to_str(&id.rand, sizeof(id.rand), &name[LengthOfGlobal], len);
+ bytes_to_str(&id.internal_pod(), sizeof(id.internal_pod()), &name[LengthOfGlobal], len);
}
- void erase_and_throw_if_error(void *hnd_val, const sync_id &id)
+ void throw_if_error(void *hnd_val)
{
if(!hnd_val){
- map_.erase(id);
error_info err(winapi::get_last_error());
throw interprocess_exception(err);
}
@@ -108,27 +128,36 @@ class sync_handles
{
NameBuf name;
fill_name(name, id);
- void *hnd_val = winapi::open_or_create_semaphore
- (name, (long)initial_count, (long)(((unsigned long)(-1))>>1), unrestricted_security.get_attributes());
- erase_and_throw_if_error(hnd_val, id);
- return hnd_val;
+ permissions unrestricted_security;
+ unrestricted_security.set_unrestricted();
+ winapi_semaphore_wrapper sem_wrapper;
+ bool created;
+ sem_wrapper.open_or_create
+ (name, (long)initial_count, winapi_semaphore_wrapper::MaxCount, unrestricted_security, created);
+ throw_if_error(sem_wrapper.handle());
+ return sem_wrapper.release();
}
void* open_or_create_mutex(const sync_id &id)
{
NameBuf name;
fill_name(name, id);
- void *hnd_val = winapi::open_or_create_mutex
- (name, false, unrestricted_security.get_attributes());
- erase_and_throw_if_error(hnd_val, id);
- return hnd_val;
+ permissions unrestricted_security;
+ unrestricted_security.set_unrestricted();
+ winapi_mutex_wrapper mtx_wrapper;
+ mtx_wrapper.open_or_create(name, unrestricted_security);
+ throw_if_error(mtx_wrapper.handle());
+ return mtx_wrapper.release();
}
public:
void *obtain_mutex(const sync_id &id, bool *popen_created = 0)
{
+ umap_type::value_type v(id, (void*)0);
scoped_lock<spin_mutex> lock(mtx_);
- void *&hnd_val = map_[id];
+ umap_type::iterator it = umap_.insert(v).first;
+ map_[&it->first] = it;
+ void *&hnd_val = it->second;
if(!hnd_val){
hnd_val = open_or_create_mutex(id);
if(popen_created) *popen_created = true;
@@ -138,8 +167,11 @@ class sync_handles
void *obtain_semaphore(const sync_id &id, unsigned int initial_count, bool *popen_created = 0)
{
+ umap_type::value_type v(id, (void*)0);
scoped_lock<spin_mutex> lock(mtx_);
- void *&hnd_val = map_[id];
+ umap_type::iterator it = umap_.insert(v).first;
+ map_[&it->first] = it;
+ void *&hnd_val = it->second;
if(!hnd_val){
hnd_val = open_or_create_semaphore(id, initial_count);
if(popen_created) *popen_created = true;
@@ -150,16 +182,35 @@ class sync_handles
void destroy_handle(const sync_id &id)
{
scoped_lock<spin_mutex> lock(mtx_);
- map_type::iterator it = map_.find(id);
- if(it != map_.end()){
+ umap_type::iterator it = umap_.find(id);
+ umap_type::iterator itend = umap_.end();
+
+ if(it != itend){
winapi::close_handle(it->second);
- map_.erase(it);
+ const map_type::key_type &k = &it->first;
+ map_.erase(k);
+ umap_.erase(it);
+ }
+ }
+
+ void destroy_syncs_in_range(const void *addr, std::size_t size)
+ {
+ sync_id low_id(addr);
+ sync_id hig_id(static_cast<const char*>(addr)+size);
+ scoped_lock<spin_mutex> lock(mtx_);
+ map_type::iterator itlow(map_.lower_bound(&low_id)),
+ ithig(map_.lower_bound(&hig_id));
+ while(itlow != ithig){
+ void *hnd = umap_[*itlow->first];
+ winapi::close_handle(hnd);
+ umap_.erase(*itlow->first);
+ itlow = map_.erase(itlow);
}
}
private:
- winapi::interprocess_all_access_security unrestricted_security;
spin_mutex mtx_;
+ umap_type umap_;
map_type map_;
};