diff options
Diffstat (limited to 'boost/interprocess/sync/windows/sync_utils.hpp')
-rw-r--r-- | boost/interprocess/sync/windows/sync_utils.hpp | 117 |
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_; }; |