$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r79514 - in trunk/boost/interprocess: . detail sync/windows
From: igaztanaga_at_[hidden]
Date: 2012-07-14 17:51:20
Author: igaztanaga
Date: 2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
New Revision: 79514
URL: http://svn.boost.org/trac/boost/changeset/79514
Log:
Intermodule singleton optimization for windows
Text files modified: 
   trunk/boost/interprocess/detail/intermodule_singleton_common.hpp   |   262 +++++++++++++++++++++------------------ 
   trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp    |     3                                         
   trunk/boost/interprocess/detail/portable_intermodule_singleton.hpp |    60 +++++++-                                
   trunk/boost/interprocess/detail/win32_api.hpp                      |    91 ++++++++++++-                           
   trunk/boost/interprocess/detail/windows_intermodule_singleton.hpp  |   248 ++++++++++++++++++++++++++++++++++++-   
   trunk/boost/interprocess/managed_shared_memory.hpp                 |     6                                         
   trunk/boost/interprocess/sync/windows/mutex.hpp                    |     4                                         
   trunk/boost/interprocess/sync/windows/named_condition.hpp          |     7                                         
   trunk/boost/interprocess/sync/windows/named_semaphore.hpp          |     5                                         
   trunk/boost/interprocess/sync/windows/named_sync.hpp               |    10                                         
   trunk/boost/interprocess/sync/windows/semaphore.hpp                |     2                                         
   trunk/boost/interprocess/sync/windows/sync_utils.hpp               |    90 ++++++++++---                           
   trunk/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp |    46 +++++-                                  
   13 files changed, 627 insertions(+), 207 deletions(-)
Modified: trunk/boost/interprocess/detail/intermodule_singleton_common.hpp
==============================================================================
--- trunk/boost/interprocess/detail/intermodule_singleton_common.hpp	(original)
+++ trunk/boost/interprocess/detail/intermodule_singleton_common.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -21,6 +21,7 @@
 #include <boost/interprocess/detail/atomic.hpp>
 #include <boost/interprocess/detail/os_thread_functions.hpp>
 #include <boost/type_traits/type_with_alignment.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
 #include <boost/assert.hpp>
 #include <cstddef>
 #include <cstdio>
@@ -44,32 +45,32 @@
    s = stream.str();
 }
 
-inline const char *get_shm_base_name()
-{  return "bip.gmem.shm.";  }
+inline const char *get_map_base_name()
+{  return "bip.gmem.map.";  }
 
-inline void get_shm_name(std::string &shm_name)
+inline void get_map_name(std::string &map_name)
 {
-   get_pid_creation_time_str(shm_name);
-   shm_name.insert(0, get_shm_base_name());
+   get_pid_creation_time_str(map_name);
+   map_name.insert(0, get_map_base_name());
 }
 
-inline std::size_t get_shm_size()
+inline std::size_t get_map_size()
 {  return 65536;  }
 
-template<class ManagedGlobalMemory>
-struct managed_sh_dependant;
+template<class ThreadSafeGlobalMap>
+struct thread_safe_global_map_dependant;
 
 }  //namespace intermodule_singleton_helpers {
 
 //This class contains common code for all singleton types, so that we instantiate this
-//code just once per module. This class also holds a shared memory manager
+//code just once per module. This class also holds a thread soafe global map
 //to be used by all instances protected with a reference count
-template<class ManagedGlobalMemory>
+template<class ThreadSafeGlobalMap>
 class intermodule_singleton_common
 {
    public:
-   typedef void*(singleton_constructor_t)(ManagedGlobalMemory &);
-   typedef void (singleton_destructor_t)(void *, ManagedGlobalMemory &);
+   typedef void*(singleton_constructor_t)(ThreadSafeGlobalMap &);
+   typedef void (singleton_destructor_t)(void *, ThreadSafeGlobalMap &);
 
    static const ::boost::uint32_t Uninitialized       = 0u;
    static const ::boost::uint32_t Initializing        = 1u;
@@ -77,11 +78,11 @@
    static const ::boost::uint32_t Broken              = 3u;
    static const ::boost::uint32_t Destroyed           = 4u;
 
-   //Initialize this_module_singleton_ptr, creates the shared memory if needed and also creates an unique
-   //opaque type in shared memory through a singleton_constructor_t function call,
+   //Initialize this_module_singleton_ptr, creates the global map if needed and also creates an unique
+   //opaque type in global map through a singleton_constructor_t function call,
    //initializing the passed pointer to that unique instance.
    //
-   //We have two concurrency types here. a)the shared memory/singleton creation must
+   //We have two concurrency types here. a)the global map/singleton creation must
    //be safe between threads of this process but in different modules/dlls. b)
    //the pointer to the singleton is per-module, so we have to protect this
    //initization between threads of the same module.
@@ -98,7 +99,7 @@
          ::boost::uint32_t previous_module_singleton_initialized = atomic_cas32
             (&this_module_singleton_initialized, Initializing, Uninitialized);
          //If the thread succeeded the CAS (winner) it will compete with other
-         //winner threads from other modules to create the shared memory
+         //winner threads from other modules to create the global map
          if(previous_module_singleton_initialized == Destroyed){
             //Trying to resurrect a dead Phoenix singleton. Just try to
             //mark it as uninitialized and start again
@@ -114,17 +115,17 @@
          }
          if(previous_module_singleton_initialized == Uninitialized){
             try{
-               //Now initialize shm, this function solves concurrency issues
+               //Now initialize the global map, this function must solve concurrency
+               //issues between threads of several modules
+               initialize_global_map_handle();
+               //Now try to create the singleton in global map.
+               //This function solves concurrency issues
                //between threads of several modules
-               initialize_shm();
+               void *tmp = constructor(get_map());
                //Increment the module reference count that reflects how many
                //singletons this module holds, so that we can safely destroy
-               //module shared memory object when no singleton is left
+               //module global map object when no singleton is left
                atomic_inc32(&this_module_singleton_count);
-               //Now try to create the singleton in shared memory.
-               //This function solves concurrency issues
-               //between threads of several modules
-               void *tmp = constructor(get_shm());
                //Insert a barrier before assigning the pointer to
                //make sure this assignment comes after the initialization
                atomic_write32(&this_module_singleton_initialized, Initializing);
@@ -177,7 +178,7 @@
          //Note: this destructor might provoke a Phoenix singleton
          //resurrection. This means that this_module_singleton_count
          //might change after this call.
-         destructor(ptr, get_shm());
+         destructor(ptr, get_map());
          ptr = 0;
 
          //Memory barrier to make sure pointer is nulled.
@@ -185,32 +186,35 @@
          atomic_write32(&this_module_singleton_initialized, Destroyed);
 
          //If this is the last singleton of this module
-         //apply shm destruction.
+         //apply map destruction.
          //Note: singletons are destroyed when the module is unloaded
          //so no threads should be executing or holding references
          //to this module
          if(1 == atomic_dec32(&this_module_singleton_count)){
-            destroy_shm();
+            destroy_global_map_handle();
          }
       }
    }
 
    private:
-   static ManagedGlobalMemory &get_shm()
+   static ThreadSafeGlobalMap &get_map()
    {
-      return *static_cast<ManagedGlobalMemory *>(static_cast<void *>(&mem_holder.shm_mem));
+      return *static_cast<ThreadSafeGlobalMap *>(static_cast<void *>(&mem_holder.map_mem));
    }
 
-   static void initialize_shm()
+   static void initialize_global_map_handle()
    {
-      //Obtain unique shm name and size
-      std::string s;
+      //Obtain unique map name and size
       while(1){
-         //Try to pass shm state to initializing
-         ::boost::uint32_t tmp = atomic_cas32(&this_module_shm_initialized, Initializing, Uninitialized);
-         if(tmp >= Initialized){
+         //Try to pass map state to initializing
+         ::boost::uint32_t tmp = atomic_cas32(&this_module_map_initialized, Initializing, Uninitialized);
+         if(tmp == Initialized || tmp == Broken){
             break;
          }
+         else if(tmp == Destroyed){
+            tmp = atomic_cas32(&this_module_map_initialized, Uninitialized, Destroyed);
+            continue;
+         }
          //If some other thread is doing the work wait
          else if(tmp == Initializing){
             thread_yield();
@@ -218,30 +222,24 @@
          else{ //(tmp == Uninitialized)
             //If not initialized try it again?
             try{
-               //Remove old shared memory from the system
-               intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::remove_old_gmem();
-               //
-               if(s.empty()){
-                  intermodule_singleton_helpers::get_shm_name(s);
-               }
-               const char *ShmName = s.c_str();
-               const std::size_t ShmSize = intermodule_singleton_helpers::get_shm_size();;
-
-               //in-place construction of the shared memory class
-               ::new (&get_shm())ManagedGlobalMemory(open_or_create, ShmName, ShmSize);
-               //Use shared memory internal lock to initialize the lock file
+               //Remove old global map from the system
+               intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>::remove_old_gmem();
+               //in-place construction of the global map class
+               intermodule_singleton_helpers::thread_safe_global_map_dependant
+                  <ThreadSafeGlobalMap>::construct_map(static_cast<void*>(&get_map()));
+               //Use global map's internal lock to initialize the lock file
                //that will mark this gmem as "in use".
-               typename intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::
-                  lock_file_logic f(get_shm());
+               typename intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>::
+                  lock_file_logic f(get_map());
                //If function failed (maybe a competing process has erased the shared
                //memory between creation and file locking), retry with a new instance.
-               if(f.retry_with_new_shm){
-                  get_shm().~ManagedGlobalMemory();
-                  atomic_write32(&this_module_shm_initialized, Destroyed);
+               if(f.retry()){
+                  get_map().~ThreadSafeGlobalMap();
+                  atomic_write32(&this_module_map_initialized, Destroyed);
                }
                else{
-                  //Locking succeeded, so this shared memory module-instance is ready
-                  atomic_write32(&this_module_shm_initialized, Initialized);
+                  //Locking succeeded, so this global map module-instance is ready
+                  atomic_write32(&this_module_map_initialized, Initialized);
                   break;
                }
             }
@@ -253,18 +251,18 @@
       }
    }
 
-   static void destroy_shm()
+   static void destroy_global_map_handle()
    {
       if(!atomic_read32(&this_module_singleton_count)){
          //This module is being unloaded, so destroy
-         //the shared memory object of this module
-         //and unlink the shared memory if it's the last
-         typename intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::
-            unlink_shmlogic f(get_shm());
-         (get_shm()).~ManagedGlobalMemory();
-         atomic_write32(&this_module_shm_initialized, Destroyed);
+         //the global map object of this module
+         //and unlink the global map if it's the last
+         typename intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>::
+            unlink_map_logic f(get_map());
+         (get_map()).~ThreadSafeGlobalMap();
+         atomic_write32(&this_module_map_initialized, Destroyed);
          //Do some cleanup for other processes old gmem instances
-         intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::remove_old_gmem();
+         intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>::remove_old_gmem();
       }
    }
 
@@ -272,32 +270,47 @@
    //this_module_singleton_count is the number of singletons used by this module
    static volatile boost::uint32_t this_module_singleton_count;
 
-   //this_module_shm_initialized is the state of this module's shm class object.
+   //this_module_map_initialized is the state of this module's map class object.
    //Values: Uninitialized, Initializing, Initialized, Broken
-   static volatile boost::uint32_t this_module_shm_initialized;
+   static volatile boost::uint32_t this_module_map_initialized;
 
-   //Raw memory to construct the shared memory manager  
+   //Raw memory to construct the global map manager  
    static struct mem_holder_t
    {
       ::boost::detail::max_align aligner;
-      char shm_mem [sizeof(ManagedGlobalMemory)];
+      char map_mem [sizeof(ThreadSafeGlobalMap)];
    } mem_holder;
 };
 
-template<class ManagedGlobalMemory>
-volatile boost::uint32_t intermodule_singleton_common<ManagedGlobalMemory>::this_module_singleton_count;
+template<class ThreadSafeGlobalMap>
+volatile boost::uint32_t intermodule_singleton_common<ThreadSafeGlobalMap>::this_module_singleton_count;
 
-template<class ManagedGlobalMemory>
-volatile boost::uint32_t intermodule_singleton_common<ManagedGlobalMemory>::this_module_shm_initialized;
+template<class ThreadSafeGlobalMap>
+volatile boost::uint32_t intermodule_singleton_common<ThreadSafeGlobalMap>::this_module_map_initialized;
+
+template<class ThreadSafeGlobalMap>
+typename intermodule_singleton_common<ThreadSafeGlobalMap>::mem_holder_t
+   intermodule_singleton_common<ThreadSafeGlobalMap>::mem_holder;
+
+//A reference count to be stored in global map holding the number
+//of singletons (one per module) attached to the instance pointed by
+//the internal ptr.
+struct ref_count_ptr
+{
+   ref_count_ptr(void *p, boost::uint32_t count)
+      : ptr(p), singleton_ref_count(count)
+   {}
+   void *ptr;
+   //This reference count serves to count the number of attached
+   //modules to this singleton
+   volatile boost::uint32_t singleton_ref_count;
+};
 
-template<class ManagedGlobalMemory>
-typename intermodule_singleton_common<ManagedGlobalMemory>::mem_holder_t
-   intermodule_singleton_common<ManagedGlobalMemory>::mem_holder;
 
 //Now this class is a singleton, initializing the singleton in
 //the first get() function call if LazyInit is false. If true
 //then the singleton will be initialized when loading the module.
-template<typename C, bool LazyInit, bool Phoenix, class ManagedGlobalMemory>
+template<typename C, bool LazyInit, bool Phoenix, class ThreadSafeGlobalMap>
 class intermodule_singleton_impl
 {
    public:
@@ -316,13 +329,13 @@
 
    static void atentry_work()
    {
-      intermodule_singleton_common<ManagedGlobalMemory>::initialize_singleton_logic
+      intermodule_singleton_common<ThreadSafeGlobalMap>::initialize_singleton_logic
          (this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor, Phoenix);
    }
 
    static void atexit_work()
    {
-      intermodule_singleton_common<ManagedGlobalMemory>::finalize_singleton_logic
+      intermodule_singleton_common<ThreadSafeGlobalMap>::finalize_singleton_logic
          (this_module_singleton_ptr, this_module_singleton_initialized, singleton_destructor);
    }
 
@@ -365,38 +378,29 @@
 
    static lifetime_type lifetime;
 
-   //A reference count to be stored in shared memory holding the number
-   //of singletons (one per module) attached to the instance pointed by
-   //the internal ptr.
-   struct ref_count_ptr
-   {
-      ref_count_ptr(C *p, boost::uint32_t count)
-         : ptr(p), singleton_ref_count(count)
-      {}
-      C *ptr;
-      //This reference count serves to count the number of attached
-      //modules to this singleton
-      volatile boost::uint32_t singleton_ref_count;
-   };
-
-   //A functor to be executed inside shared memory lock that just
-   //searches for the singleton in shm and if not present creates a new one.
+   //A functor to be executed inside global map lock that just
+   //searches for the singleton in map and if not present creates a new one.
    //If singleton constructor throws, the exception is propagated
    struct init_atomic_func
    {
-      init_atomic_func(ManagedGlobalMemory &m)
-         : mshm(m)
+      init_atomic_func(ThreadSafeGlobalMap &m)
+         : m_map(m)
       {}
 
       void operator()()
       {
-         ref_count_ptr *rcount = mshm.template find<ref_count_ptr>(unique_instance).first;
+         ref_count_ptr *rcount = intermodule_singleton_helpers::thread_safe_global_map_dependant
+            <ThreadSafeGlobalMap>::find(m_map, typeid(C).name());
          if(!rcount){
-            C *p = new C();
+            C *p = new C;
             try{
-               rcount = mshm.template construct<ref_count_ptr>(unique_instance)(p, 0u);
+               ref_count_ptr val(p, 0u);
+               rcount = intermodule_singleton_helpers::thread_safe_global_map_dependant
+                           <ThreadSafeGlobalMap>::insert(m_map, typeid(C).name(), val);
             }
             catch(...){
+               intermodule_singleton_helpers::thread_safe_global_map_dependant
+                           <ThreadSafeGlobalMap>::erase(m_map, typeid(C).name());
                delete p;
                throw;
             }
@@ -407,66 +411,80 @@
          atomic_inc32(&rcount->singleton_ref_count);
          ret_ptr = rcount->ptr;
       }
-      ManagedGlobalMemory &mshm;
+      void *data() const 
+         { return ret_ptr;  }
+
+      private:
+      ThreadSafeGlobalMap &m_map;
       void *ret_ptr;
    };
 
-   //A functor to be executed inside shared memory lock that just
-   //deletes the singleton in shm if the attached count reaches to zero
+   //A functor to be executed inside global map lock that just
+   //deletes the singleton in map if the attached count reaches to zero
    struct fini_atomic_func
    {
-      fini_atomic_func(ManagedGlobalMemory &m)
-         : mshm(m)
+      fini_atomic_func(ThreadSafeGlobalMap &m)
+         : m_map(m)
       {}
 
       void operator()()
       {
-         ref_count_ptr *rcount = mshm.template find<ref_count_ptr>(unique_instance).first;
+         ref_count_ptr *rcount = intermodule_singleton_helpers::thread_safe_global_map_dependant
+            <ThreadSafeGlobalMap>::find(m_map, typeid(C).name());
             //The object must exist
          BOOST_ASSERT(rcount);
+         BOOST_ASSERT(rcount->singleton_ref_count > 0);
          //Check if last reference
          if(atomic_dec32(&rcount->singleton_ref_count) == 1){
             //If last, destroy the object
             BOOST_ASSERT(rcount->ptr != 0);
-            delete rcount->ptr;
-            //Now destroy shm entry
-            bool destroyed = mshm.template destroy<ref_count_ptr>(unique_instance);
+            C *pc = static_cast<C*>(rcount->ptr);
+            //Now destroy map entry
+            bool destroyed = intermodule_singleton_helpers::thread_safe_global_map_dependant
+                        <ThreadSafeGlobalMap>::erase(m_map, typeid(C).name());
             (void)destroyed;  BOOST_ASSERT(destroyed == true);
+            delete pc;
          }
       }
-      ManagedGlobalMemory &mshm;
+      void *data() const
+         { return ret_ptr;  }
+      
+      private:
+      ThreadSafeGlobalMap &m_map;
       void *ret_ptr;
    };
 
    //A wrapper to execute init_atomic_func
-   static void *singleton_constructor(ManagedGlobalMemory &mshm)
+   static void *singleton_constructor(ThreadSafeGlobalMap &map)
    {
-      init_atomic_func f(mshm);
-      mshm.atomic_func(f);
-      return f.ret_ptr;
+      init_atomic_func f(map);
+      intermodule_singleton_helpers::thread_safe_global_map_dependant
+                  <ThreadSafeGlobalMap>::atomic_func(map, f);
+      return f.data();
    }
 
    //A wrapper to execute fini_atomic_func
-   static void singleton_destructor(void *p, ManagedGlobalMemory &mshm)
+   static void singleton_destructor(void *p, ThreadSafeGlobalMap &map)
    {  (void)p;
-      fini_atomic_func f(mshm);
-      mshm.atomic_func(f);
+      fini_atomic_func f(map);
+      intermodule_singleton_helpers::thread_safe_global_map_dependant
+                  <ThreadSafeGlobalMap>::atomic_func(map, f);
    }
 };
 
-template <typename C, bool L, bool P, class ManagedGlobalMemory>
-volatile int intermodule_singleton_impl<C, L, P, ManagedGlobalMemory>::lifetime_type_lazy::m_dummy = 0;
+template <typename C, bool L, bool P, class ThreadSafeGlobalMap>
+volatile int intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::lifetime_type_lazy::m_dummy = 0;
 
 //These will be zero-initialized by the loader
-template <typename C, bool L, bool P, class ManagedGlobalMemory>
-void *intermodule_singleton_impl<C, L, P, ManagedGlobalMemory>::this_module_singleton_ptr = 0;
+template <typename C, bool L, bool P, class ThreadSafeGlobalMap>
+void *intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::this_module_singleton_ptr = 0;
 
-template <typename C, bool L, bool P, class ManagedGlobalMemory>
-volatile boost::uint32_t intermodule_singleton_impl<C, L, P, ManagedGlobalMemory>::this_module_singleton_initialized = 0;
+template <typename C, bool L, bool P, class ThreadSafeGlobalMap>
+volatile boost::uint32_t intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::this_module_singleton_initialized = 0;
 
-template <typename C, bool L, bool P, class ManagedGlobalMemory>
-typename intermodule_singleton_impl<C, L, P, ManagedGlobalMemory>::lifetime_type
-   intermodule_singleton_impl<C, L, P, ManagedGlobalMemory>::lifetime;
+template <typename C, bool L, bool P, class ThreadSafeGlobalMap>
+typename intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::lifetime_type
+   intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::lifetime;
 
 }  //namespace ipcdetail{
 }  //namespace interprocess{
Modified: trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp	(original)
+++ trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -396,7 +396,8 @@
 
             if(previous == UninitializedSegment){
                try{
-                  construct_func(static_cast<char*>(region.get_address()) + ManagedOpenOrCreateUserOffset, size - ManagedOpenOrCreateUserOffset, true);
+                  construct_func( static_cast<char*>(region.get_address()) + ManagedOpenOrCreateUserOffset
+                                , size - ManagedOpenOrCreateUserOffset, true);
                   //All ok, just move resources to the external mapped region
                   m_mapped_region.swap(region);
                }
Modified: trunk/boost/interprocess/detail/portable_intermodule_singleton.hpp
==============================================================================
--- trunk/boost/interprocess/detail/portable_intermodule_singleton.hpp	(original)
+++ trunk/boost/interprocess/detail/portable_intermodule_singleton.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -104,7 +104,7 @@
 }
 
 template<>
-struct managed_sh_dependant<managed_global_memory>
+struct thread_safe_global_map_dependant<managed_global_memory>
 {
    private:
    static const int GMemMarkToBeRemoved = -1;
@@ -161,7 +161,7 @@
          }
          //If done, then the process is dead so take global shared memory name
          //(the name is based on the lock file name) and try to apply erasure logic
-         str.insert(0, get_shm_base_name());
+         str.insert(0, get_map_base_name());
          try{
             managed_global_memory shm(open_only, str.c_str());
             gmem_erase_func func(str.c_str(), filepath, shm);
@@ -201,7 +201,7 @@
 
       void operator()(void)
       {
-         retry_with_new_shm = false;
+         retry_with_new_map = false;
 
          //First find the file locking descriptor id
          locking_file_serial_id *pserial_id =
@@ -229,9 +229,9 @@
             if(fd < 0){
                this->register_lock_file(GMemMarkToBeRemoved);
                std::string s;
-               get_shm_name(s);
+               get_map_name(s);
                shared_memory_object::remove(s.c_str());
-               retry_with_new_shm = true;
+               retry_with_new_map = true;
             }
             //If successful, register the file descriptor
             else{
@@ -242,7 +242,7 @@
          //should retry creation logic, since this shm might have been already
          //unlinked since the shm was removed
          else if (fd == GMemMarkToBeRemoved){
-            retry_with_new_shm = true;
+            retry_with_new_map = true;
          }
          //If the stored fd is not valid (a open fd, a normal file with the
          //expected size, or does not have the same file id number,
@@ -254,9 +254,9 @@
                !compare_file_serial(fd, *pserial_id)){
             pserial_id->fd = GMemMarkToBeRemoved;
             std::string s;
-            get_shm_name(s);
+            get_map_name(s);
             shared_memory_object::remove(s.c_str());
-            retry_with_new_shm = true;
+            retry_with_new_map = true;
          }
          else{
             //If the lock file is ok, increment reference count of
@@ -265,6 +265,8 @@
          }
       }
 
+      bool retry() const { return retry_with_new_map; }
+
       private:
       locking_file_serial_id * register_lock_file(int fd)
       {
@@ -273,16 +275,25 @@
          return pinfo;
       }
 
-      public:
       managed_global_memory &mshm;
-      bool retry_with_new_shm;
+      bool retry_with_new_map;
    };
 
-   struct unlink_shmlogic
+   static void construct_map(void *addr)
    {
-      unlink_shmlogic(managed_global_memory &mshm)
+      std::string s;
+      intermodule_singleton_helpers::get_map_name(s);
+      const char *MapName = s.c_str();
+      const std::size_t MapSize = intermodule_singleton_helpers::get_map_size();;
+      ::new (addr)managed_global_memory(open_or_create, MapName, MapSize);
+   }
+
+   struct unlink_map_logic
+   {
+      unlink_map_logic(managed_global_memory &mshm)
          : mshm_(mshm)
       {  mshm.atomic_func(*this);  }
+
       void operator()()
       {
          locking_file_serial_id *pserial_id =
@@ -297,13 +308,36 @@
                create_and_get_singleton_lock_file_path(s);
                delete_file(s.c_str());
                close_lock_file(fd);
-               intermodule_singleton_helpers::get_shm_name(s);
+               intermodule_singleton_helpers::get_map_name(s);
                shared_memory_object::remove(s.c_str());
             }
          }
       }
+
+      private:
       managed_global_memory &mshm_;
    };
+
+   static ref_count_ptr *find(managed_global_memory &map, const char *name)
+   {
+      return map.find<ref_count_ptr>(name).first;
+   }
+
+   static ref_count_ptr *insert(managed_global_memory &map, const char *name, const ref_count_ptr &ref)
+   {
+      return map.construct<ref_count_ptr>(name)(ref);
+   }
+
+   static bool erase(managed_global_memory &map, const char *name)
+   {
+      return map.destroy<ref_count_ptr>(name);
+   }
+
+   template<class F>
+   static void atomic_func(managed_global_memory &map, F &f)
+   {
+      map.atomic_func(f);
+   }
 };
 
 }  //namespace intermodule_singleton_helpers {
Modified: trunk/boost/interprocess/detail/win32_api.hpp
==============================================================================
--- trunk/boost/interprocess/detail/win32_api.hpp	(original)
+++ trunk/boost/interprocess/detail/win32_api.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -46,6 +46,7 @@
 //Some used constants
 static const unsigned long infinite_time        = 0xFFFFFFFF;
 static const unsigned long error_already_exists = 183L;
+static const unsigned long error_invalid_handle = 6L;
 static const unsigned long error_sharing_violation = 32L;
 static const unsigned long error_file_not_found = 2u;
 static const unsigned long error_no_more_files  = 18u;
@@ -137,7 +138,14 @@
 static const unsigned long sublang_default      = (unsigned long)0x01;
 static const unsigned long invalid_file_size    = (unsigned long)0xFFFFFFFF;
 static const unsigned long invalid_file_attributes =  ((unsigned long)-1);
-static       void * const  invalid_handle_value = (void*)(long)(-1);
+static       void * const  invalid_handle_value = ((void*)(long)(-1));
+
+static const unsigned long file_type_char    =  0x0002L;
+static const unsigned long file_type_disk    =  0x0001L;
+static const unsigned long file_type_pipe    =  0x0003L;
+static const unsigned long file_type_remote  =  0x8000L;
+static const unsigned long file_type_unknown =  0x0000L;
+
 static const unsigned long create_new        = 1;
 static const unsigned long create_always     = 2;
 static const unsigned long open_existing     = 3;
@@ -580,6 +588,13 @@
         unsigned int limit;		// max semaphore count
 };
 
+struct interprocess_section_basic_information
+{
+  void *          base_address;
+  unsigned long   section_attributes;
+  __int64         section_size;
+};
+
 struct interprocess_filetime
 { 
    unsigned long  dwLowDateTime; 
@@ -789,6 +804,12 @@
    object_data_information
 };
 
+enum section_information_class
+{
+   section_basic_information,
+   section_image_information
+};
+
 struct object_name_information_t
 {
    unicode_string_t Name;
@@ -813,6 +834,7 @@
    , void *hTargetProcessHandle,    void **lpTargetHandle
    , unsigned long dwDesiredAccess, int bInheritHandle
    , unsigned long dwOptions);
+extern "C" __declspec(dllimport) long __stdcall GetFileType(void *hFile);
 extern "C" __declspec(dllimport) void *__stdcall FindFirstFileA(const char *lpFileName, win32_find_data_t *lpFindFileData);
 extern "C" __declspec(dllimport) int   __stdcall FindNextFileA(void *hFindFile, win32_find_data_t *lpFindFileData);
 extern "C" __declspec(dllimport) int   __stdcall FindClose(void *hFindFile);
@@ -905,6 +927,7 @@
 typedef long (__stdcall *NtQuerySystemInformation_t)(int, void*, unsigned long, unsigned long *);
 typedef long (__stdcall *NtQueryObject_t)(void*, object_information_class, void *, unsigned long, unsigned long *);
 typedef long (__stdcall *NtQuerySemaphore_t)(void*, unsigned int info_class, interprocess_semaphore_basic_information *pinfo, unsigned int info_size, unsigned int *ret_len);
+typedef long (__stdcall *NtQuerySection_t)(void*, section_information_class, interprocess_section_basic_information *pinfo, unsigned long info_size, unsigned long *ret_len);
 typedef long (__stdcall *NtQueryInformationFile_t)(void *,io_status_block_t *,void *, long, int);
 typedef long (__stdcall *NtOpenFile_t)(void*,unsigned long ,object_attributes_t*,io_status_block_t*,unsigned long,unsigned long);
 typedef long (__stdcall *NtClose_t) (void*);
@@ -989,6 +1012,12 @@
       , lpTargetHandle,       0,                0
       , duplicate_same_access);
 }
+
+inline long get_file_type(void *hFile)
+{
+   return GetFileType(hFile);
+}
+
 /*
 inline void get_system_time_as_file_time(interprocess_filetime *filetime)
 {  GetSystemTimeAsFileTime(filetime);  }
@@ -1012,6 +1041,9 @@
 inline void *open_or_create_semaphore(const char *name, long initial_count, long maximum_count, interprocess_security_attributes *attr)
 {  return CreateSemaphoreA(attr, initial_count, maximum_count, name);  }
 
+inline void *open_semaphore(const char *name)
+{  return OpenSemaphoreA(semaphore_all_access, 0, name);  }
+
 inline int release_semaphore(void *handle, long release_count, long *prev_count)
 {  return ReleaseSemaphore(handle, release_count, prev_count); }
 
@@ -1039,16 +1071,21 @@
    {  return &sa; }
 };
 
-inline void * create_file_mapping (void * handle, unsigned long access, unsigned long high_size, unsigned long low_size, const char * name, interprocess_security_attributes *psec)
+inline void * create_file_mapping (void * handle, unsigned long access, unsigned __int64 file_offset, const char * name, interprocess_security_attributes *psec)
 {
+   const unsigned long high_size(file_offset >> 32), low_size((boost::uint32_t)file_offset);
    return CreateFileMappingA (handle, psec, access, high_size, low_size, name);
 }
 
 inline void * open_file_mapping (unsigned long access, const char *name)
 {  return OpenFileMappingA (access, 0, name);   }
 
-inline void *map_view_of_file_ex(void *handle, unsigned long file_access, unsigned long highoffset, unsigned long lowoffset, std::size_t numbytes, void *base_addr)
-{  return MapViewOfFileEx(handle, file_access, highoffset, lowoffset, numbytes, base_addr);  }
+inline void *map_view_of_file_ex(void *handle, unsigned long file_access, unsigned __int64 offset, std::size_t numbytes, void *base_addr)
+{
+   const unsigned long offset_low  = (unsigned long)(offset & ((unsigned __int64)0xFFFFFFFF));
+   const unsigned long offset_high = offset >> 32;
+   return MapViewOfFileEx(handle, file_access, offset_high, offset_low, numbytes, base_addr);
+}
 
 inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes, interprocess_security_attributes *psec)
 {
@@ -1191,7 +1228,7 @@
 template<int Dummy>
 struct function_address_holder
 {
-   enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NtQuerySemaphore, NumFunction };
+   enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NtQuerySemaphore, NtQuerySection, NumFunction };
    enum { NtDll_dll, NumModule };
 
    private:
@@ -1228,7 +1265,7 @@
    static void *get_address_from_dll(const unsigned int id)
    {
       assert(id < (unsigned int)NumFunction);
-      const char *function[] = { "NtSetInformationFile", "NtQuerySystemInformation", "NtQueryObject", "NtQuerySemaphore" };
+      const char *function[] = { "NtSetInformationFile", "NtQuerySystemInformation", "NtQueryObject", "NtQuerySemaphore", "NtQuerySection" };
       bool compile_check[sizeof(function)/sizeof(function[0]) == NumFunction];
       (void)compile_check;
       return get_proc_address(get_module(NtDll_dll), function[id]);
@@ -1300,10 +1337,10 @@
    bool bSuccess = false;
 
    // Create a file mapping object.
-   void * hFileMap = create_file_mapping(hFile, page_readonly, 0, 1, 0, 0);
+   void * hFileMap = create_file_mapping(hFile, page_readonly, 1, 0, 0);
    if(hFileMap){
       // Create a file mapping to get the file name.
-      void* pMem = map_view_of_file_ex(hFileMap, file_map_read, 0, 0, 1, 0);
+      void* pMem = map_view_of_file_ex(hFileMap, file_map_read, 0, 1, 0);
 
       if (pMem){
          //out_length = pfGMFN(get_current_process(), pMem, pszFilename, MaxPath);
@@ -1398,9 +1435,12 @@
 class handle_closer
 {
    void *handle_;
+   handle_closer(const handle_closer &);
+   handle_closer& operator=(const handle_closer &);
    public:
-   handle_closer(void *handle) : handle_(handle){}
-   ~handle_closer(){ close_handle(handle_);  }
+   explicit handle_closer(void *handle) : handle_(handle){}
+   ~handle_closer()
+   {  close_handle(handle_);  }
 };
 
 union ntquery_mem_t
@@ -1729,6 +1769,37 @@
                 (attrib & file_attribute_directory));
 }
 
+inline bool get_file_mapping_size(void *file_mapping_hnd, __int64 &size)
+{
+   NtQuerySection_t pNtQuerySection =
+      (NtQuerySection_t)dll_func::get(dll_func::NtQuerySection);
+   //Obtain file name
+   interprocess_section_basic_information info;
+   unsigned long ntstatus =
+      pNtQuerySection(file_mapping_hnd, section_basic_information, &info, sizeof(info), 0);
+   if(ntstatus){
+      return false;
+   }
+   size = info.section_size;
+   return true;
+}
+
+inline bool get_semaphore_info(void *handle, long &count, long &limit)
+{
+   winapi::interprocess_semaphore_basic_information info;
+   winapi::NtQuerySemaphore_t pNtQuerySemaphore =
+         (winapi::NtQuerySemaphore_t)dll_func::get(winapi::dll_func::NtQuerySemaphore);
+   unsigned int ret_len;
+   long status = pNtQuerySemaphore(handle, winapi::semaphore_basic_information, &info, sizeof(info), &ret_len);
+   if(status){
+      return false;
+   }
+   count = info.count;
+   limit = info.limit;
+   return true;
+}
+
+
 }  //namespace winapi
 }  //namespace interprocess
 }  //namespace boost
Modified: trunk/boost/interprocess/detail/windows_intermodule_singleton.hpp
==============================================================================
--- trunk/boost/interprocess/detail/windows_intermodule_singleton.hpp	(original)
+++ trunk/boost/interprocess/detail/windows_intermodule_singleton.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -22,21 +22,217 @@
    #error "This header can't be included from non-windows operating systems"
 #endif
 
-#include <boost/interprocess/detail/managed_global_memory.hpp>
-#include <boost/interprocess/detail/intermodule_singleton_common.hpp>
-#include <boost/interprocess/windows_shared_memory.hpp>
 #include <boost/assert.hpp>
+#include <boost/interprocess/detail/intermodule_singleton_common.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/cstdint.hpp>
+#include <string>
+#include <map>
 
 namespace boost{
 namespace interprocess{
 namespace ipcdetail{
 
-typedef basic_managed_global_memory<windows_shared_memory, false>  windows_managed_global_memory;
-
 namespace intermodule_singleton_helpers {
 
+//This global map will be implemented using 3 sync primitives:
+//
+//1)  A named mutex that will implement global mutual exclusion between
+//    threads from different modules/dlls
+//
+//2)  A semaphore that will act as a global counter for modules attached to the global map
+//    so that the global map can be destroyed when the last module is detached.
+//
+//3)  A semaphore that will be hacked to hold the address of a heap-allocated map in the
+//    max and current semaphore count.
+class windows_semaphore_based_map
+{
+   typedef std::map<std::string, ref_count_ptr> map_type;
+
+   public:
+   windows_semaphore_based_map()
+   {
+      map_type *m = new map_type;
+      boost::uint32_t initial_count = 0;
+      boost::uint32_t max_count = 0;
+
+      //Windows user address space sizes:
+      //32 bit windows: [32 bit processes] 2GB or 3GB (31/32 bits)
+      //64 bit windows: [32 bit processes] 2GB or 4GB (31/32 bits)
+      //                [64 bit processes] 2GB or 8TB (31/43 bits)
+      //
+      //Windows semaphores use 'long' parameters (32 bits in LLP64 data model) and
+      //those values can't be negative, so we have 31 bits to store something
+      //in max_count and initial count parameters.
+      //Also, max count must be bigger than 0 and bigger or equal than initial count.
+      if(sizeof(void*) == sizeof(boost::uint32_t)){
+         //This means that for 32 bit processes, a semaphore count (31 usable bits) is 
+         //enough to store 4 byte aligned memory (4GB -> 32 bits - 2 bits = 30 bits). 
+         //The max count will hold the pointer value and current semaphore count
+         //will be zero.
+         //
+         //Relying in UB with a cast through union, but all known windows compilers
+         //accept this (C11 also accepts this).
+         union caster_union
+         {
+            void *addr;
+            boost::uint32_t addr_uint32;
+         } caster;
+         caster.addr = m;
+         //memory is at least 4 byte aligned in windows
+         BOOST_ASSERT((caster.addr_uint32 & boost::uint32_t(3)) == 0);
+         max_count = caster.addr_uint32 >> 2;
+      }
+      else if(sizeof(void*) == sizeof(boost::uint64_t)){
+         //Relying in UB with a cast through union, but all known windows compilers
+         //accept this (C11 accepts this).
+         union caster_union
+         {
+            void *addr;
+            boost::uint64_t addr_uint64;
+         } caster;
+         caster.addr = m;
+         //We'll encode the address using 30 bits in each 32 bit high and low parts.
+         //High part will be the sem max count, low part will be the sem initial count.
+         //(restrictions: max count > 0, initial count >= 0 and max count >= initial count):
+         //
+         // - Low part will be shifted two times (4 byte alignment) so that top
+         //   two bits are cleared (the top one for sign, the next one to
+         //   assure low part value is always less than the high part value.
+         // - The top bit of the high part will be cleared and the next bit will be 1
+         //   (so high part is always bigger than low part due to the quasi-top bit).
+         //
+         //   This means that the addresses we can store must be 4 byte aligned
+         //   and less than 1 ExbiBytes ( 2^60 bytes, ~1 ExaByte). User-level address space in Windows 64
+         //   is much less than this (8TB, 2^43 bytes): "1 EByte (or it was 640K?) ought to be enough for anybody" ;-).
+         caster.addr = m;
+         BOOST_ASSERT((caster.addr_uint64 & boost::uint64_t(3)) == 0);
+         max_count = boost::uint32_t(caster.addr_uint64 >> 32);
+         initial_count = boost::uint32_t(caster.addr_uint64);
+         initial_count = initial_count/4;
+         //Make sure top two bits are zero
+         BOOST_ASSERT((max_count & boost::uint32_t(0xC0000000)) == 0);
+         //Set quasi-top bit
+         max_count |= boost::uint32_t(0x40000000);
+      }
+      bool created = false;
+      const permissions & perm = permissions();
+      std::string pid_creation_time, name;
+      get_pid_creation_time_str(pid_creation_time);
+      name = "bipc_gmap_sem_lock_";
+      name += pid_creation_time;
+      bool success = m_mtx_lock.open_or_create(name.c_str(), perm);
+      name = "bipc_gmap_sem_count_";
+      name += pid_creation_time;
+      scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+      {
+         success = success && m_sem_count.open_or_create
+            ( name.c_str(), static_cast<long>(0), winapi_semaphore_wrapper::MaxCount, perm, created);
+         name = "bipc_gmap_sem_map_";
+         name += pid_creation_time;
+         success = success && m_sem_map.open_or_create
+            (name.c_str(), initial_count, max_count, perm, created);
+         if(!success){
+            //winapi_xxx wrappers do the cleanup...
+            throw int(0);
+         }
+         if(!created){
+            delete m;
+         }
+         else{
+            BOOST_ASSERT(&get_map_unlocked() == m);
+         }
+         m_sem_count.post();
+      }
+   }
+
+   map_type &get_map_unlocked()
+   {
+      if(sizeof(void*) == sizeof(boost::uint32_t)){
+         union caster_union
+         {
+            void *addr;
+            boost::uint32_t addr_uint32;
+         } caster;
+         caster.addr = 0;
+         caster.addr_uint32 = m_sem_map.limit();
+         caster.addr_uint32 = caster.addr_uint32 << 2;
+         return *static_cast<map_type*>(caster.addr);
+      }
+      else{
+         union caster_union
+         {
+            void *addr;
+            boost::uint64_t addr_uint64;
+         } caster;
+         boost::uint32_t max_count(m_sem_map.limit()), initial_count(m_sem_map.value());
+         //Clear quasi-top bit
+         max_count &= boost::uint32_t(0xBFFFFFFF);
+         caster.addr_uint64 = max_count;
+         caster.addr_uint64 =  caster.addr_uint64 << 32;
+         caster.addr_uint64 |= boost::uint64_t(initial_count) << 2;
+         return *static_cast<map_type*>(caster.addr);
+      }
+   }
+
+   ref_count_ptr *find(const char *name)
+   {
+      scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+      map_type &map = this->get_map_unlocked();
+      map_type::iterator it = map.find(std::string(name));
+      if(it != map.end()){
+         return &it->second;
+      }
+      else{
+         return 0;
+      }
+   }
+
+   ref_count_ptr * insert(const char *name, const ref_count_ptr &ref)
+   {
+      scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+      map_type &map = this->get_map_unlocked();
+      map_type::iterator it = map.insert(map_type::value_type(std::string(name), ref)).first;
+      return &it->second;
+   }
+
+   bool erase(const char *name)
+   {
+      scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+      map_type &map = this->get_map_unlocked();
+      return map.erase(std::string(name)) != 0;
+   }
+
+   template<class F>
+   void atomic_func(F &f)
+   {
+      scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+      f();
+   }
+
+   ~windows_semaphore_based_map()
+   {
+      scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+      m_sem_count.wait();
+      if(0 == m_sem_count.value()){
+         delete &this->get_map_unlocked();
+      }
+      //First close sems to protect this with the external mutex
+      m_sem_map.close();
+      m_sem_count.close();
+      //Once scoped_lock unlocks the mutex, the destructor will close the handle...
+   }
+   
+   private:
+   winapi_mutex_wrapper     m_mtx_lock;
+   winapi_semaphore_wrapper m_sem_map;
+   winapi_semaphore_wrapper m_sem_count;
+};
+
 template<>
-struct managed_sh_dependant<windows_managed_global_memory>
+struct thread_safe_global_map_dependant<windows_semaphore_based_map>
 {
    static void apply_gmem_erase_logic(const char *, const char *){}
 
@@ -45,20 +241,48 @@
 
    struct lock_file_logic
    {
-      lock_file_logic(windows_managed_global_memory &)
-         : retry_with_new_shm(false)
+      lock_file_logic(windows_semaphore_based_map &)
+         : retry_with_new_map(false)
       {}
 
       void operator()(void){}
-      const bool retry_with_new_shm;
+      bool retry() const { return retry_with_new_map; }
+      private:
+      const bool retry_with_new_map;
    };
 
-   struct unlink_shmlogic
+   static void construct_map(void *addr)
+   {
+      ::new (addr)windows_semaphore_based_map;
+   }
+
+   struct unlink_map_logic
    {
-      unlink_shmlogic(windows_managed_global_memory &)
+      unlink_map_logic(windows_semaphore_based_map &)
       {}
       void operator()(){}
    };
+
+   static ref_count_ptr *find(windows_semaphore_based_map &map, const char *name)
+   {
+      return map.find(name);
+   }
+
+   static ref_count_ptr * insert(windows_semaphore_based_map &map, const char *name, const ref_count_ptr &ref)
+   {
+      return map.insert(name, ref);
+   }
+
+   static bool erase(windows_semaphore_based_map &map, const char *name)
+   {
+      return map.erase(name);
+   }
+
+   template<class F>
+   static void atomic_func(windows_semaphore_based_map &map, F &f)
+   {
+      map.atomic_func(f);
+   }
 };
 
 }  //namespace intermodule_singleton_helpers {
@@ -69,7 +293,7 @@
       < C
       , LazyInit
       , Phoenix
-      , windows_managed_global_memory
+      , intermodule_singleton_helpers::windows_semaphore_based_map
       >
 {};
 
Modified: trunk/boost/interprocess/managed_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_shared_memory.hpp	(original)
+++ trunk/boost/interprocess/managed_shared_memory.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -187,12 +187,6 @@
       return base_t::template shrink_to_fit
          <basic_managed_shared_memory>(shmname);
    }
-
-   bool flush()
-   {
-      return this->base2_t::flush();
-   }
-
    /// @cond
 
    //!Tries to find a previous named allocation address. Returns a memory
Modified: trunk/boost/interprocess/sync/windows/mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/windows/mutex.hpp	(original)
+++ trunk/boost/interprocess/sync/windows/mutex.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -49,13 +49,13 @@
 };
 
 inline windows_mutex::windows_mutex()
-   : id_()
+   : id_(this)
 {
    sync_handles &handles =
       windows_intermodule_singleton<sync_handles>::get();
    //Create mutex with the initial count
    bool open_or_created;
-   handles.obtain_mutex(this->id_, &open_or_created);
+   (void)handles.obtain_mutex(this->id_, &open_or_created);
    //The mutex must be created, never opened
    assert(open_or_created);
    assert(open_or_created && winapi::get_last_error() != winapi::error_already_exists);
Modified: trunk/boost/interprocess/sync/windows/named_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/windows/named_condition.hpp	(original)
+++ trunk/boost/interprocess/sync/windows/named_condition.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -176,14 +176,17 @@
          //sem_block_queue
          aux_str += "_bq";
          winapi_semaphore_wrapper sem_block_queue;
-         if(!sem_block_queue.open_or_create(aux_str.c_str(), sem_counts[0], perm))
+         bool created;
+         if(!sem_block_queue.open_or_create
+            (aux_str.c_str(), sem_counts[0], winapi_semaphore_wrapper::MaxCount, perm, created))
             return false;
          aux_str.erase(pos);
 
          //sem_block_lock
          aux_str += "_bl";
          winapi_semaphore_wrapper sem_block_lock;
-         if(!sem_block_lock.open_or_create(aux_str.c_str(), sem_counts[1], perm))
+         if(!sem_block_lock.open_or_create
+            (aux_str.c_str(), sem_counts[1], winapi_semaphore_wrapper::MaxCount, perm, created))
             return false;
          aux_str.erase(pos);
 
Modified: trunk/boost/interprocess/sync/windows/named_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/windows/named_semaphore.hpp	(original)
+++ trunk/boost/interprocess/sync/windows/named_semaphore.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -90,7 +90,10 @@
          //
          permissions sem_perm;
          sem_perm.set_unrestricted();
-         return m_sem_wrapper.open_or_create(aux_str.c_str(), static_cast<long>(m_sem_count), sem_perm);
+         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()
Modified: trunk/boost/interprocess/sync/windows/named_sync.hpp
==============================================================================
--- trunk/boost/interprocess/sync/windows/named_sync.hpp	(original)
+++ trunk/boost/interprocess/sync/windows/named_sync.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -102,7 +102,6 @@
    , windows_named_sync_interface &sync_interface)
 {
    std::string aux_str(name);
-   sync_id::internal_type unique_id_val;
    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
@@ -123,7 +122,8 @@
       if(m_file_hnd != winapi::invalid_handle_value){
          //Now lock the file
          const std::size_t buflen = sync_interface.get_data_size();
-         const std::size_t sizeof_file_info = sizeof(unique_id_val) + buflen;
+         typedef __int64 unique_id_type;
+         const std::size_t sizeof_file_info = sizeof(unique_id_type) + buflen;
          winapi::interprocess_overlapped overlapped;
          if(winapi::lock_file_ex
             (m_file_hnd, winapi::lockfile_exclusive_lock, 0, sizeof_file_info, 0, &overlapped)){
@@ -132,10 +132,10 @@
             //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);
-                  sync_id unique_id;
-                  unique_id_val = unique_id.rand;
+                  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)  &&
@@ -145,7 +145,7 @@
                      success = true;
                   }
                   winapi::get_file_size(m_file_hnd, filesize);
-                  assert(filesize == sizeof_file_info);
+                  assert(std::size_t(filesize) == sizeof_file_info);
                }
                else{
                   void *buf = sync_interface.buffer_to_store_init_data_from_file();
Modified: trunk/boost/interprocess/sync/windows/semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/windows/semaphore.hpp	(original)
+++ trunk/boost/interprocess/sync/windows/semaphore.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -48,7 +48,7 @@
 };
 
 inline windows_semaphore::windows_semaphore(unsigned int initialCount)
-   : id_()
+   : id_(this)
 {
    sync_handles &handles =
       windows_intermodule_singleton<sync_handles>::get();
Modified: trunk/boost/interprocess/sync/windows/sync_utils.hpp
==============================================================================
--- trunk/boost/interprocess/sync/windows/sync_utils.hpp	(original)
+++ trunk/boost/interprocess/sync/windows/sync_utils.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -24,6 +24,7 @@
 #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 {
@@ -52,22 +53,36 @@
    return true;
 }
 
-struct sync_id
+class sync_id
 {
+   public:
    typedef __int64 internal_type;
-   internal_type rand;
+   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_;  }
 
-   sync_id()
-   {  winapi::query_performance_counter(&rand);  }
+   internal_type &internal_pod()
+   {  return rand_;  }
 
-   explicit sync_id(internal_type val)
-   {  rand = val;  }
+   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;  }
+   {  return l.rand_ == r.rand_ && l.map_addr_ == r.map_addr_;  }
+
+   private:
+   internal_type rand_;
+   const void * const map_addr_;
 };
 
 class sync_handles
@@ -76,11 +91,19 @@
    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";
@@ -90,13 +113,12 @@
          ++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);
       }
@@ -109,8 +131,10 @@
       permissions unrestricted_security;
       unrestricted_security.set_unrestricted();
       winapi_semaphore_wrapper sem_wrapper;
-      sem_wrapper.open_or_create(name, (long)initial_count, unrestricted_security);
-      erase_and_throw_if_error(sem_wrapper.handle(), id);
+      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();
    }
 
@@ -122,15 +146,18 @@
       unrestricted_security.set_unrestricted();
       winapi_mutex_wrapper mtx_wrapper;
       mtx_wrapper.open_or_create(name, unrestricted_security);
-      erase_and_throw_if_error(mtx_wrapper.handle(), id);
+      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;
@@ -140,8 +167,11 @@
 
    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;
@@ -152,15 +182,35 @@
    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:
    spin_mutex mtx_;
+   umap_type umap_;
    map_type map_;
 };
 
Modified: trunk/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp
==============================================================================
--- trunk/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp	(original)
+++ trunk/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp	2012-07-14 17:51:18 EDT (Sat, 14 Jul 2012)
@@ -93,17 +93,20 @@
       }
    }
 
-   unsigned int value() const
+   long value() const
    {
-      winapi::interprocess_semaphore_basic_information info;
-      winapi::NtQuerySemaphore_t pNtQuerySemaphore =
-            (winapi::NtQuerySemaphore_t)winapi::dll_func::get(winapi::dll_func::NtQuerySemaphore);
-      unsigned int ret_len;
-      long status = pNtQuerySemaphore(m_sem_hnd, winapi::semaphore_basic_information, &info, sizeof(info), &ret_len);
-      if(status){
+      long count, limit;
+      if(!winapi::get_semaphore_info(m_sem_hnd, count, limit))
          return 0;
-      }
-      return info.count;
+      return count;
+   }
+
+   long limit() const
+   {
+      long count, limit;
+      if(!winapi::get_semaphore_info(m_sem_hnd, count, limit))
+         return 0;
+      return limit;
    }
 
    /// @cond
@@ -122,6 +125,9 @@
 
    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)
    {}
@@ -139,21 +145,37 @@
    void *handle() const
    {  return m_sem_hnd; }
 
-   bool open_or_create(const char *name, long sem_count, const permissions &perm)
+   bool open_or_create( const char *name
+                      , long sem_count
+                      , long max_count
+                      , const permissions &perm
+                      , bool &created)
    {
       if(m_sem_hnd == winapi::invalid_handle_value){
          m_sem_hnd = winapi::open_or_create_semaphore
             ( name
             , sem_count
-            , (std::numeric_limits<long>::max)()
+            , 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()
    {