$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r77912 - in trunk/boost/interprocess: detail smart_ptr smart_ptr/detail sync sync/detail sync/shm sync/windows
From: igaztanaga_at_[hidden]
Date: 2012-04-11 02:27:53
Author: igaztanaga
Date: 2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
New Revision: 77912
URL: http://svn.boost.org/trac/boost/changeset/77912
Log:
Reworked native windows process-shared synchronization utilities.
Added:
   trunk/boost/interprocess/detail/file_locking_helpers.hpp   (contents, props changed)
   trunk/boost/interprocess/detail/intermodule_singleton_common.hpp   (contents, props changed)
   trunk/boost/interprocess/detail/managed_global_memory.hpp   (contents, props changed)
   trunk/boost/interprocess/detail/portable_intermodule_singleton.hpp   (contents, props changed)
   trunk/boost/interprocess/detail/windows_intermodule_singleton.hpp   (contents, props changed)
   trunk/boost/interprocess/sync/detail/
   trunk/boost/interprocess/sync/detail/condition_algorithm_8a.hpp   (contents, props changed)
   trunk/boost/interprocess/sync/windows/named_condition.hpp   (contents, props changed)
   trunk/boost/interprocess/sync/windows/named_mutex.hpp   (contents, props changed)
   trunk/boost/interprocess/sync/windows/named_recursive_mutex.hpp   (contents, props changed)
   trunk/boost/interprocess/sync/windows/named_semaphore.hpp   (contents, props changed)
   trunk/boost/interprocess/sync/windows/named_sync.hpp   (contents, props changed)
   trunk/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp   (contents, props changed)
   trunk/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/interprocess/detail/atomic.hpp                     |   169 ++---                                   
   trunk/boost/interprocess/detail/config_begin.hpp               |     1                                         
   trunk/boost/interprocess/detail/intermodule_singleton.hpp      |  1142 --------------------------------------- 
   trunk/boost/interprocess/detail/os_file_functions.hpp          |    12                                         
   trunk/boost/interprocess/detail/pointer_type.hpp               |     2                                         
   trunk/boost/interprocess/detail/preprocessor.hpp               |    30                                         
   trunk/boost/interprocess/detail/robust_emulation.hpp           |     4                                         
   trunk/boost/interprocess/detail/tmp_dir_helpers.hpp            |   163 ++--                                    
   trunk/boost/interprocess/detail/win32_api.hpp                  |    29                                         
   trunk/boost/interprocess/detail/workaround.hpp                 |   125 +--                                     
   trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp     |     2                                         
   trunk/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp  |     2                                         
   trunk/boost/interprocess/smart_ptr/shared_ptr.hpp              |     7                                         
   trunk/boost/interprocess/sync/interprocess_condition.hpp       |     6                                         
   trunk/boost/interprocess/sync/interprocess_mutex.hpp           |     6                                         
   trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp |     6                                         
   trunk/boost/interprocess/sync/interprocess_semaphore.hpp       |     6                                         
   trunk/boost/interprocess/sync/named_condition.hpp              |    16                                         
   trunk/boost/interprocess/sync/named_mutex.hpp                  |    27                                         
   trunk/boost/interprocess/sync/named_recursive_mutex.hpp        |    14                                         
   trunk/boost/interprocess/sync/named_semaphore.hpp              |    11                                         
   trunk/boost/interprocess/sync/shm/named_condition.hpp          |    11                                         
   trunk/boost/interprocess/sync/windows/condition.hpp            |   311 +---------                              
   trunk/boost/interprocess/sync/windows/mutex.hpp                |    55 -                                       
   trunk/boost/interprocess/sync/windows/semaphore.hpp            |    57 -                                       
   trunk/boost/interprocess/sync/windows/sync_utils.hpp           |    39                                         
   26 files changed, 440 insertions(+), 1813 deletions(-)
Modified: trunk/boost/interprocess/detail/atomic.hpp
==============================================================================
--- trunk/boost/interprocess/detail/atomic.hpp	(original)
+++ trunk/boost/interprocess/detail/atomic.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -117,23 +117,6 @@
                         : "cc");
 
    return prev;
-/*
-   asm volatile( "lock\n\t"
-                 "cmpxchg %3,%1"
-               : "=a" (prev), "=m" (*(mem))
-               : "0" (prev), "r" (with)
-               : "memory", "cc");
-*/
-/*
-   boost::uint32_t prev;
-
-   asm volatile ("lock; cmpxchgl %1, %2"             
-               : "=a" (prev)               
-               : "r" (with), "m" (*(mem)), "0"(cmp));
-   asm volatile("" : : : "memory");
-
-   return prev;
-*/
 }
 
 //! Atomically add 'val' to an boost::uint32_t
@@ -158,14 +141,6 @@
    );
 
    return r;
-/*
-   asm volatile( "lock\n\t; xaddl %0,%1"
-               : "=r"(val), "=m"(*mem)
-               : "0"(val), "m"(*mem));
-   asm volatile("" : : : "memory");
-
-   return val;
-*/
 }
 
 //! Atomically increment an apr_uint32_t by 1
@@ -208,17 +183,14 @@
 {
    boost::uint32_t prev, temp;
 
-   asm volatile ("0:\n\t"                 // retry local label     
-               "lwarx  %0,0,%2\n\t"       // load prev and reserve 
-               "add    %1,%0,%3\n\t"      // temp = prev + val   
-               "stwcx. %1,0,%2\n\t"       // conditionally store   
-               "bne-   0b"                // start over if we lost
-                                          // the reservation
-               //XXX find a cleaner way to define the temp         
-               //it's not an output
-               : "=&r" (prev), "=&r" (temp)        // output, temp 
-               : "b" (mem), "r" (val)              // inputs       
-               : "memory", "cc");                  // clobbered    
+   asm volatile ("1:\n\t"
+                 "lwarx  %0,0,%2\n\t"
+                 "add    %1,%0,%3\n\t"
+                 "stwcx. %1,0,%2\n\t"
+                 "bne-   1b"
+                 : "=&r" (prev), "=&r" (temp)
+                 : "b" (mem), "r" (val)
+                 : "cc", "memory");
    return prev;
 }
 
@@ -233,19 +205,16 @@
 {
    boost::uint32_t prev;
 
-   asm volatile ("0:\n\t"                 // retry local label     
-               "lwarx  %0,0,%1\n\t"       // load prev and reserve 
-               "cmpw   %0,%3\n\t"         // does it match cmp?    
-               "bne-   1f\n\t"            // ...no, bail out       
-               "stwcx. %2,0,%1\n\t"       // ...yes, conditionally
-                                          //   store with            
-               "bne-   0b\n\t"            // start over if we lost
-                                          //   the reservation       
-               "1:"                       // exit local label      
-
-               : "=&r"(prev)                        // output      
-               : "b" (mem), "r" (with), "r"(cmp)    // inputs      
-               : "memory", "cc");                   // clobbered   
+   asm volatile ("1:\n\t"
+                 "lwarx  %0,0,%1\n\t"
+                 "cmpw   %0,%3\n\t"
+                 "bne-   2f\n\t"
+                 "stwcx. %2,0,%1\n\t"
+                 "bne-   1b\n\t"
+                 "2:"
+                 : "=&r"(prev)
+                 : "b" (mem), "r"(cmp), "r" (with)
+                 : "cc", "memory");
    return prev;
 }
 
@@ -275,56 +244,6 @@
 }  //namespace interprocess{
 }  //namespace boost{
 
-#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
-
-namespace boost {
-namespace interprocess {
-namespace ipcdetail{
-
-//! Atomically add 'val' to an boost::uint32_t
-//! "mem": pointer to the object
-//! "val": amount to add
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_add32
-   (volatile boost::uint32_t *mem, boost::uint32_t val)
-{  return __sync_fetch_and_add(const_cast<boost::uint32_t *>(mem), val);   }
-
-//! Atomically increment an apr_uint32_t by 1
-//! "mem": pointer to the object
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
-{  return atomic_add32(mem, 1);  }
-
-//! Atomically decrement an boost::uint32_t by 1
-//! "mem": pointer to the atomic value
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
-{  return atomic_add32(mem, (boost::uint32_t)-1);   }
-
-//! Atomically read an boost::uint32_t from memory
-inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
-{  return *mem;   }
-
-//! Compare an boost::uint32_t's value with "cmp".
-//! If they are the same swap the value with "with"
-//! "mem": pointer to the value
-//! "with" what to swap it with
-//! "cmp": the value to compare it to
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_cas32
-   (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
-{  return __sync_val_compare_and_swap(const_cast<boost::uint32_t *>(mem), cmp, with);   }
-
-//! Atomically set an boost::uint32_t in memory
-//! "mem": pointer to the object
-//! "param": val value that the object will assume
-inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{  *mem = val; }
-
-}  //namespace ipcdetail{
-}  //namespace interprocess{
-}  //namespace boost{
-
 #elif (defined(sun) || defined(__sun))
 
 #include <atomic.h>
@@ -561,7 +480,57 @@
 
 }  //namespace ipcdetail  
 }  //namespace interprocess  
-}  //namespace boost  
+}  //namespace boost
+
+#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail{
+
+//! Atomically add 'val' to an boost::uint32_t
+//! "mem": pointer to the object
+//! "val": amount to add
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_add32
+   (volatile boost::uint32_t *mem, boost::uint32_t val)
+{  return __sync_fetch_and_add(const_cast<boost::uint32_t *>(mem), val);   }
+
+//! Atomically increment an apr_uint32_t by 1
+//! "mem": pointer to the object
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
+{  return atomic_add32(mem, 1);  }
+
+//! Atomically decrement an boost::uint32_t by 1
+//! "mem": pointer to the atomic value
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
+{  return atomic_add32(mem, (boost::uint32_t)-1);   }
+
+//! Atomically read an boost::uint32_t from memory
+inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
+{  return *mem;   }
+
+//! Compare an boost::uint32_t's value with "cmp".
+//! If they are the same swap the value with "with"
+//! "mem": pointer to the value
+//! "with" what to swap it with
+//! "cmp": the value to compare it to
+//! Returns the old value of *mem
+inline boost::uint32_t atomic_cas32
+   (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
+{  return __sync_val_compare_and_swap(const_cast<boost::uint32_t *>(mem), cmp, with);   }
+
+//! Atomically set an boost::uint32_t in memory
+//! "mem": pointer to the object
+//! "param": val value that the object will assume
+inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
+{  *mem = val; }
+
+}  //namespace ipcdetail{
+}  //namespace interprocess{
+}  //namespace boost{
 
 #else
 
Modified: trunk/boost/interprocess/detail/config_begin.hpp
==============================================================================
--- trunk/boost/interprocess/detail/config_begin.hpp	(original)
+++ trunk/boost/interprocess/detail/config_begin.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -44,4 +44,5 @@
                                     //    with /GR-; unpredictable behavior may result
    #pragma warning (disable : 4673) //  throwing '' the following types will not be considered at the catch site
    #pragma warning (disable : 4671) //  the copy constructor is inaccessible
+   #pragma warning (disable : 4250) //  inherits 'x' via dominance
 #endif
Added: trunk/boost/interprocess/detail/file_locking_helpers.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/file_locking_helpers.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,298 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-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_FILE_LOCKING_HELPERS_HPP
+#define BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <sstream>
+#include <string>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <cstddef>
+#include <boost/interprocess/detail/os_file_functions.hpp>
+
+#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
+
+#if defined(BOOST_INTERPROCESS_WINDOWS)
+
+#include <fcntl.h>
+#include <io.h>
+#include <sys/locking.h>
+
+#else //defined(BOOST_INTERPROCESS_WINDOWS)
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#endif   //defined(BOOST_INTERPROCESS_WINDOWS)
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail{
+
+#if defined(BOOST_INTERPROCESS_WINDOWS)
+
+struct locking_file_serial_id
+{
+   int fd;
+   unsigned long dwVolumeSerialNumber;
+   unsigned long nFileIndexHigh;
+   unsigned long nFileIndexLow;
+   //This reference count counts the number of modules attached
+   //to the shared memory and lock file. This serves to unlink
+   //the locking file and shared memory when all modules are
+   //done with the global memory (shared memory)
+   volatile boost::uint32_t modules_attached_to_gmem_count;
+};
+
+inline bool lock_locking_file(int fd)
+{
+   int ret = 0;
+   while(ret != 0 && errno == EDEADLK){
+      ret = _locking(fd, _LK_LOCK, 1/*lock_file_contents_length()*/);
+   }
+   return 0 == ret;
+}
+
+inline bool try_lock_locking_file(int fd)
+{
+   return 0 == _locking(fd, _LK_NBLCK , 1);
+}
+
+inline int open_or_create_and_lock_file(const char *name)
+{
+   permissions p;
+   p.set_unrestricted();
+   while(1){
+      file_handle_t handle = create_or_open_file(name, read_write, p);
+      int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
+      if(fd < 0){
+         close_file(handle);
+         return fd;
+      }
+      if(!try_lock_locking_file(fd)){
+         _close(fd);
+         return -1;
+      }
+      struct _stat s;
+      if(0 == _stat(name, &s)){
+         return fd;
+      }
+      else{
+         _close(fd);
+      }
+   }
+}
+
+inline int try_open_and_lock_file(const char *name)
+{
+   file_handle_t handle = open_existing_file(name, read_write);
+   int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
+   if(fd < 0){
+      close_file(handle);
+      return fd;
+   }
+   if(!try_lock_locking_file(fd)){
+      _close(fd);
+      return -1;
+   }
+   return fd;
+}
+
+inline void close_lock_file(int fd)
+{  _close(fd); }
+
+inline bool is_valid_fd(int fd)
+{
+   struct _stat s;
+   return EBADF != _fstat(fd, &s);
+}
+
+inline bool is_normal_file(int fd)
+{
+   if(_isatty(fd))
+      return false;
+   struct _stat s;
+   if(0 != _fstat(fd, &s))
+      return false;
+   return 0 != (s.st_mode & _S_IFREG);
+}
+
+inline std::size_t get_size(int fd)
+{
+   struct _stat s;
+   if(0 != _fstat(fd, &s))
+      return 0u;
+   return (std::size_t)s.st_size;
+}
+
+inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
+{
+   winapi::interprocess_by_handle_file_information info;
+   if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
+      return false;
+   id.fd = fd;
+   id.dwVolumeSerialNumber = info.dwVolumeSerialNumber;
+   id.nFileIndexHigh = info.nFileIndexHigh;
+   id.nFileIndexLow = info.nFileIndexLow;
+   id.modules_attached_to_gmem_count = 1; //Initialize attached count
+   return true;
+}
+
+inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
+{
+   winapi::interprocess_by_handle_file_information info;
+   if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
+      return false;
+
+   return   id.dwVolumeSerialNumber == info.dwVolumeSerialNumber  &&
+            id.nFileIndexHigh       == info.nFileIndexHigh        &&
+            id.nFileIndexLow        == info.nFileIndexLow;
+}
+
+#else //UNIX
+
+struct locking_file_serial_id
+{
+   int fd;
+   dev_t st_dev;
+   ino_t st_ino;
+   //This reference count counts the number of modules attached
+   //to the shared memory and lock file. This serves to unlink
+   //the locking file and shared memory when all modules are
+   //done with the global memory (shared memory)
+   volatile boost::uint32_t modules_attached_to_gmem_count;
+};
+
+inline bool lock_locking_file(int fd)
+{
+   int ret = 0;
+   while(ret != 0 && errno != EINTR){
+      struct flock lock;
+      lock.l_type = F_WRLCK;
+      lock.l_whence = SEEK_SET;
+      lock.l_start = 0;
+      lock.l_len = 1;
+      ret = fcntl (fd, F_SETLKW, &lock);
+   }
+   return 0 == ret;
+}
+
+inline bool try_lock_locking_file(int fd)
+{
+   struct flock lock;
+   lock.l_type = F_WRLCK;
+   lock.l_whence = SEEK_SET;
+   lock.l_start = 0;
+   lock.l_len = 1;
+   return 0 == fcntl (fd, F_SETLK, &lock);
+}
+
+inline int open_or_create_and_lock_file(const char *name)
+{
+   permissions p;
+   p.set_unrestricted();
+   while(1){
+      int fd = create_or_open_file(name, read_write, p);
+      if(fd < 0){
+         return fd;
+      }
+      if(!try_lock_locking_file(fd)){
+         close(fd);
+         return -1;
+      }
+      struct stat s;
+      if(0 == stat(name, &s)){
+         return fd;
+      }
+      else{
+         close(fd);
+      }
+   }
+}
+
+inline int try_open_and_lock_file(const char *name)
+{
+   int fd = open_existing_file(name, read_write);
+   if(fd < 0){
+      return fd;
+   }
+   if(!try_lock_locking_file(fd)){
+      close(fd);
+      return -1;
+   }
+   return fd;
+}
+
+inline void close_lock_file(int fd)
+{  close(fd); }
+
+inline bool is_valid_fd(int fd)
+{
+   struct stat s;
+   return EBADF != fstat(fd, &s);
+}
+
+inline bool is_normal_file(int fd)
+{
+   struct stat s;
+   if(0 != fstat(fd, &s))
+      return false;
+   return 0 != (s.st_mode & S_IFREG);
+}
+
+inline std::size_t get_size(int fd)
+{
+   struct stat s;
+   if(0 != fstat(fd, &s))
+      return 0u;
+   return (std::size_t)s.st_size;
+}
+
+inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
+{
+   struct stat s;
+   if(0 != fstat(fd, &s))
+      return false;
+   id.fd = fd;
+   id.st_dev = s.st_dev;
+   id.st_ino = s.st_ino;
+   id.modules_attached_to_gmem_count = 1; //Initialize attached count
+   return true;
+}
+
+inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
+{
+   struct stat info;
+   if(0 != fstat(fd, &info))
+      return false;
+
+   return   id.st_dev == info.st_dev  &&
+            id.st_ino == info.st_ino;
+}
+
+#endif   
+
+}  //namespace ipcdetail{
+}  //namespace interprocess{
+}  //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif   //BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP
Modified: trunk/boost/interprocess/detail/intermodule_singleton.hpp
==============================================================================
--- trunk/boost/interprocess/detail/intermodule_singleton.hpp	(original)
+++ trunk/boost/interprocess/detail/intermodule_singleton.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -18,1150 +18,15 @@
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
 
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-#include <boost/interprocess/windows_shared_memory.hpp>
-#endif
-
-#include <boost/interprocess/shared_memory_object.hpp>
-
-#include <boost/interprocess/offset_ptr.hpp>
-#include <boost/interprocess/sync/spin/mutex.hpp>
-#include <boost/interprocess/sync/spin/recursive_mutex.hpp>
-#include <boost/interprocess/detail/managed_memory_impl.hpp>
-#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
-#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>  
-#include <boost/interprocess/indexes/iset_index.hpp>
-#include <boost/interprocess/creation_tags.hpp>
-#include <boost/interprocess/permissions.hpp>
-
-
-#include <boost/interprocess/detail/atomic.hpp>
-#include <boost/interprocess/detail/os_thread_functions.hpp>
-#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
-#include <boost/interprocess/detail/os_file_functions.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/type_traits/type_with_alignment.hpp>
-#include <boost/assert.hpp>
-#include <cstddef>
-#include <cstdio>
-#include <cstring>
-#include <string>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-#include <fcntl.h>
-#include <io.h>
-
-#include <sys/locking.h>
-#else
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
+#ifdef BOOST_INTERPROCESS_WINDOWS
+   #include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
 #endif
+#include <boost/interprocess/detail/portable_intermodule_singleton.hpp>
 
 namespace boost{
 namespace interprocess{
 namespace ipcdetail{
 
-struct intermodule_singleton_mutex_family
-{
-   typedef boost::interprocess::ipcdetail::spin_mutex              mutex_type;
-   typedef boost::interprocess::ipcdetail::spin_recursive_mutex    recursive_mutex_type;
-};
-
-struct intermodule_types
-{
-   //We must use offset_ptr since a loaded DLL can map the singleton holder shared memory
-   //at a different address than other DLLs/main executables
-   typedef rbtree_best_fit<intermodule_singleton_mutex_family, offset_ptr<void> > mem_algo;
-   template<class Device, bool FileBased>
-   struct open_or_create
-   {
-      typedef managed_open_or_create_impl
-            <Device, mem_algo::Alignment, FileBased> type;
-   };
-};
-
-template<class Device, bool FileBased>
-class basic_managed_global_memory 
-   : public basic_managed_memory_impl
-      < char
-      , intermodule_types::mem_algo
-      , iset_index
-      , intermodule_types::open_or_create<Device, FileBased>::type::ManagedOpenOrCreateUserOffset
-      >
-   , private intermodule_types::open_or_create<Device, FileBased>::type
-{
-   /// @cond
-   typedef typename intermodule_types::template open_or_create<Device, FileBased>::type base2_t;
-
-   typedef basic_managed_memory_impl
-      < char
-      , intermodule_types::mem_algo
-      , iset_index
-      , base2_t::ManagedOpenOrCreateUserOffset
-      > base_t;
-
-   typedef create_open_func<base_t>        create_open_func_t;
-
-   basic_managed_global_memory *get_this_pointer()
-   {  return this;   }
-
-   public:
-   typedef typename base_t::size_type              size_type;
-
-   private:
-   typedef typename base_t::char_ptr_holder_t   char_ptr_holder_t;
-   BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_managed_global_memory)
-   /// @endcond
-
-   public: //functions
-/*
-   basic_managed_global_memory()
-   {}
-
-   basic_managed_global_memory(create_only_t create_only, const char *name,
-                             size_type size, const void *addr = 0, const permissions& perm = permissions())
-      : base_t()
-      , base2_t(create_only, name, size, read_write, addr, 
-                create_open_func_t(get_this_pointer(), DoCreate), perm)
-   {}
-*/
-   basic_managed_global_memory (open_or_create_t open_or_create,
-                              const char *name, size_type size, 
-                              const void *addr = 0, const permissions& perm = permissions())
-      : base_t()
-      , base2_t(open_or_create, name, size, read_write, addr, 
-                create_open_func_t(get_this_pointer(), 
-                DoOpenOrCreate), perm)
-   {}
-
-   basic_managed_global_memory (open_only_t open_only, const char* name, 
-                                const void *addr = 0)
-      : base_t()
-      , base2_t(open_only, name, read_write, addr, 
-                create_open_func_t(get_this_pointer(), 
-                DoOpen))
-   {}
-
-/*
-   basic_managed_global_memory (open_copy_on_write_t, const char* name, 
-                                const void *addr = 0)
-      : base_t()
-      , base2_t(open_only, name, copy_on_write, addr, 
-                create_open_func_t(get_this_pointer(), 
-                DoOpen))
-   {}
-
-   //!Connects to a created shared memory and its segment manager.
-   //!in read-only mode.
-   //!This can throw.
-   basic_managed_global_memory (open_read_only_t, const char* name, 
-                                const void *addr = 0)
-      : base_t()
-      , base2_t(open_only, name, read_only, addr, 
-                create_open_func_t(get_this_pointer(), 
-                DoOpen))
-   {}
-
-   //!Moves the ownership of "moved"'s managed memory to *this.
-   //!Does not throw
-   basic_managed_global_memory(BOOST_RV_REF(basic_managed_global_memory) moved)
-   {
-      basic_managed_global_memory tmp;
-      this->swap(moved);
-      tmp.swap(moved);
-   }
-
-   //!Moves the ownership of "moved"'s managed memory to *this.
-   //!Does not throw
-   basic_managed_global_memory &operator=(BOOST_RV_REF(basic_managed_global_memory) moved)
-   {
-      basic_managed_global_memory tmp(boost::move(moved));
-      this->swap(tmp);
-      return *this;
-   }*/
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-typedef basic_managed_global_memory<windows_shared_memory, false>  windows_managed_global_memory;
-#endif
-
-typedef basic_managed_global_memory<shared_memory_object, true>    managed_global_memory;
-
-namespace file_locking_helpers {
-
-inline void get_pid_creation_time_str(std::string &s)
-{
-   std::stringstream stream;
-   stream << get_current_process_id() << '_';
-   stream.precision(6);
-   stream << std::fixed << get_current_process_creation_time();
-   s = stream.str();
-}
-
-inline void create_tmp_subdir_and_get_pid_based_filepath(const char *subdir_name, const char *file_prefix, OS_process_id_t pid, std::string &s, bool creation_time = false)
-{
-   //Let's create a lock file for each process gmem that will mark if
-   //the process is alive or not
-   create_tmp_and_clean_old(s);
-   s += "/";
-   s += subdir_name;
-   if(!open_or_create_directory(s.c_str())){
-      throw interprocess_exception(error_info(system_error_code()));
-   }
-   s += "/";
-   s += file_prefix;
-   if(creation_time){
-      std::string sstamp;   
-      get_pid_creation_time_str(sstamp);
-      s += sstamp;
-   }
-   else{
-      pid_str_t pid_str;
-      get_pid_str(pid_str, pid);
-      s += pid_str;
-   }
-}
-
-inline bool check_if_filename_complies_with_pid
-   (const char *filename, const char *prefix, OS_process_id_t pid, std::string &file_suffix, bool creation_time = false)
-{
-   //Check if filename complies with lock file name pattern
-   std::string fname(filename);
-   std::string fprefix(prefix);
-   if(fname.size() <= fprefix.size()){
-      return false;
-   }
-   fname.resize(fprefix.size());
-   if(fname != fprefix){
-      return false;
-   }
-
-   //If not our lock file, delete it if we can lock it
-   fname = filename;
-   fname.erase(0, fprefix.size());
-   pid_str_t pid_str;
-   get_pid_str(pid_str, pid);
-   file_suffix = pid_str;
-   if(creation_time){
-      std::size_t p = fname.find('_');
-      if (p == std::string::npos){
-         return false;
-      }
-      std::string save_suffix(fname);
-      fname.erase(p);
-      fname.swap(file_suffix);
-      bool ret = (file_suffix == fname);
-      file_suffix.swap(save_suffix);
-      return ret;
-   }
-   else{
-      fname.swap(file_suffix);
-      return (file_suffix == fname);
-   }
-}
-
-}  //file_locking_helpers
-
-namespace intermodule_singleton_helpers {
-
-const int GMemMarkToBeRemoved = -1;
-const int GMemNotPresent      = -2;
-
-inline const char *get_lock_file_subdir_name()
-{  return "gmem";  }
-
-inline const char *get_lock_file_base_name()
-{  return "lck";  }
-
-inline void create_and_get_singleton_lock_file_path(std::string &s)
-{
-   file_locking_helpers::create_tmp_subdir_and_get_pid_based_filepath
-      (get_lock_file_subdir_name(), get_lock_file_base_name(), get_current_process_id(), s, true);
-}
-
-inline const char *get_shm_base_name()
-{  return "bip.gmem.shm.";  }
-
-inline void get_shm_name(std::string &shm_name)
-{
-   file_locking_helpers::get_pid_creation_time_str(shm_name);
-   shm_name.insert(0, get_shm_base_name());
-}
-
-inline std::size_t get_shm_size()
-{  return 65536;  }
-
-template<class ManagedShMem>
-struct managed_sh_dependant
-{
-   static void apply_gmem_erase_logic(const char *filepath, const char *filename);
-
-   static bool remove_old_gmem()
-   {
-      std::string refcstrRootDirectory;
-      tmp_folder(refcstrRootDirectory);
-      refcstrRootDirectory += "/";
-      refcstrRootDirectory += get_lock_file_subdir_name();
-      return for_each_file_in_dir(refcstrRootDirectory.c_str(), apply_gmem_erase_logic);
-   }
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<>
-struct managed_sh_dependant<windows_managed_global_memory>
-{
-   static void apply_gmem_erase_logic(const char *, const char *){}
-
-   static bool remove_old_gmem()
-   { return true; }
-};
-
-
-struct locking_file_serial_id
-{
-   int fd;
-   unsigned long dwVolumeSerialNumber;
-   unsigned long nFileIndexHigh;
-   unsigned long nFileIndexLow;
-   //This reference count counts the number of modules attached
-   //to the shared memory and lock file. This serves to unlink
-   //the locking file and shared memory when all modules are
-   //done with the global memory (shared memory)
-   volatile boost::uint32_t modules_attached_to_gmem_count;
-};
-
-inline bool lock_locking_file(int fd)
-{
-   int ret = 0;
-   while(ret != 0 && errno == EDEADLK){
-      ret = _locking(fd, _LK_LOCK, 1/*lock_file_contents_length()*/);
-   }
-   return 0 == ret;
-}
-
-inline bool try_lock_locking_file(int fd)
-{
-   return 0 == _locking(fd, _LK_NBLCK , 1);
-}
-
-inline int open_or_create_and_lock_file(const char *name)
-{
-   permissions p;
-   p.set_unrestricted();
-   while(1){
-      file_handle_t handle = create_or_open_file(name, read_write, p);
-      int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
-      if(fd < 0){
-         close_file(handle);
-         return fd;
-      }
-      if(!try_lock_locking_file(fd)){
-         _close(fd);
-         return -1;
-      }
-      struct _stat s;
-      if(0 == _stat(name, &s)){
-         return fd;
-      }
-      else{
-         _close(fd);
-      }
-   }
-}
-
-inline int try_open_and_lock_file(const char *name)
-{
-   file_handle_t handle = open_existing_file(name, read_write);
-   int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
-   if(fd < 0){
-      close_file(handle);
-      return fd;
-   }
-   if(!try_lock_locking_file(fd)){
-      _close(fd);
-      return -1;
-   }
-   return fd;
-}
-
-inline void close_lock_file(int fd)
-{  _close(fd); }
-
-inline bool is_valid_fd(int fd)
-{
-   struct _stat s;
-   return EBADF != _fstat(fd, &s);
-}
-
-inline bool is_normal_file(int fd)
-{
-   if(_isatty(fd))
-      return false;
-   struct _stat s;
-   if(0 != _fstat(fd, &s))
-      return false;
-   return 0 != (s.st_mode & _S_IFREG);
-}
-
-inline std::size_t get_size(int fd)
-{
-   struct _stat s;
-   if(0 != _fstat(fd, &s))
-      return 0u;
-   return (std::size_t)s.st_size;
-}
-
-inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
-{
-   winapi::interprocess_by_handle_file_information info;
-   if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
-      return false;
-   id.fd = fd;
-   id.dwVolumeSerialNumber = info.dwVolumeSerialNumber;
-   id.nFileIndexHigh = info.nFileIndexHigh;
-   id.nFileIndexLow = info.nFileIndexLow;
-   id.modules_attached_to_gmem_count = 1; //Initialize attached count
-   return true;
-}
-
-inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
-{
-   winapi::interprocess_by_handle_file_information info;
-   if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
-      return false;
-
-   return   id.dwVolumeSerialNumber == info.dwVolumeSerialNumber  &&
-            id.nFileIndexHigh       == info.nFileIndexHigh        &&
-            id.nFileIndexLow        == info.nFileIndexLow;
-}
-
-#else //UNIX
-
-struct locking_file_serial_id
-{
-   int fd;
-   dev_t st_dev;
-   ino_t st_ino;
-   //This reference count counts the number of modules attached
-   //to the shared memory and lock file. This serves to unlink
-   //the locking file and shared memory when all modules are
-   //done with the global memory (shared memory)
-   volatile boost::uint32_t modules_attached_to_gmem_count;
-};
-
-inline bool lock_locking_file(int fd)
-{
-   int ret = 0;
-   while(ret != 0 && errno != EINTR){
-      struct flock lock;
-      lock.l_type = F_WRLCK;
-      lock.l_whence = SEEK_SET;
-      lock.l_start = 0;
-      lock.l_len = 1;
-      ret = fcntl (fd, F_SETLKW, &lock);
-   }
-   return 0 == ret;
-}
-
-inline bool try_lock_locking_file(int fd)
-{
-   struct flock lock;
-   lock.l_type = F_WRLCK;
-   lock.l_whence = SEEK_SET;
-   lock.l_start = 0;
-   lock.l_len = 1;
-   return 0 == fcntl (fd, F_SETLK, &lock);
-}
-
-inline int open_or_create_and_lock_file(const char *name)
-{
-   permissions p;
-   p.set_unrestricted();
-   while(1){
-      int fd = create_or_open_file(name, read_write, p);
-      if(fd < 0){
-         return fd;
-      }
-      if(!try_lock_locking_file(fd)){
-         close(fd);
-         return -1;
-      }
-      struct stat s;
-      if(0 == stat(name, &s)){
-         return fd;
-      }
-      else{
-         close(fd);
-      }
-   }
-}
-
-inline int try_open_and_lock_file(const char *name)
-{
-   int fd = open_existing_file(name, read_write);
-   if(fd < 0){
-      return fd;
-   }
-   if(!try_lock_locking_file(fd)){
-      close(fd);
-      return -1;
-   }
-   return fd;
-}
-
-inline void close_lock_file(int fd)
-{  close(fd); }
-
-inline bool is_valid_fd(int fd)
-{
-   struct stat s;
-   return EBADF != fstat(fd, &s);
-}
-
-inline bool is_normal_file(int fd)
-{
-   struct stat s;
-   if(0 != fstat(fd, &s))
-      return false;
-   return 0 != (s.st_mode & S_IFREG);
-}
-
-inline std::size_t get_size(int fd)
-{
-   struct stat s;
-   if(0 != fstat(fd, &s))
-      return 0u;
-   return (std::size_t)s.st_size;
-}
-
-inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
-{
-   struct stat s;
-   if(0 != fstat(fd, &s))
-      return false;
-   id.fd = fd;
-   id.st_dev = s.st_dev;
-   id.st_ino = s.st_ino;
-   id.modules_attached_to_gmem_count = 1; //Initialize attached count
-   return true;
-}
-
-inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
-{
-   struct stat info;
-   if(0 != fstat(fd, &info))
-      return false;
-
-   return   id.st_dev == info.st_dev  &&
-            id.st_ino == info.st_ino;
-}
-
-#endif
-
-template<class ManagedShMem>
-struct gmem_erase_func
-{
-   gmem_erase_func(const char *shm_name, const char *singleton_lock_file_path, ManagedShMem & shm)
-      :shm_name_(shm_name), singleton_lock_file_path_(singleton_lock_file_path), shm_(shm)
-   {}
-
-   void operator()()
-   {
-      locking_file_serial_id *pserial_id = shm_.template find<locking_file_serial_id>("lock_file_fd").first;
-      if(pserial_id){
-         pserial_id->fd = GMemMarkToBeRemoved;
-      }
-      delete_file(singleton_lock_file_path_);
-      shared_memory_object::remove(shm_name_);
-   }
-   
-   const char * const shm_name_;
-   const char * const singleton_lock_file_path_;
-   ManagedShMem & shm_;
-};
-
-//This function applies shared memory erasure logic based on the passed lock file.
-template<class ManagedShMem>
-void managed_sh_dependant<ManagedShMem>::
-   apply_gmem_erase_logic(const char *filepath, const char *filename)
-{
-   int fd = GMemMarkToBeRemoved;
-   try{
-      std::string str;
-      //If the filename is current process lock file, then avoid it
-      if(file_locking_helpers::check_if_filename_complies_with_pid
-         (filename, get_lock_file_base_name(), get_current_process_id(), str, true)){
-         return;
-      }
-      //Open and lock the other process' lock file
-      fd = try_open_and_lock_file(filepath);
-      if(fd < 0){
-         return;
-      }
-      //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());
-      try{
-         ManagedShMem shm(open_only, str.c_str());
-         gmem_erase_func<ManagedShMem> func(str.c_str(), filepath, shm);
-         shm.try_atomic_func(func);
-      }
-      catch(interprocess_exception &e){
-         //If shared memory is not found erase the lock file
-         if(e.get_error_code() == not_found_error){
-            delete_file(filepath);
-         }
-      }
-   }
-   catch(...){
-
-   }
-   if(fd >= 0){
-      close_lock_file(fd);
-   }
-}
-
-}  //namespace intermodule_singleton_helpers {
-
-
-
-namespace intermodule_singleton_helpers {
-
-//The lock file logic creates uses a unique instance to a file
-template <class ManagedShMem>
-struct lock_file_logic
-{
-   lock_file_logic(ManagedShMem &shm)
-      : mshm(shm)
-   {  shm.atomic_func(*this); }
-
-   void operator()(void)
-   {
-      retry_with_new_shm = false;
-
-      //First find the file locking descriptor id
-      locking_file_serial_id *pserial_id =
-         mshm.template find<locking_file_serial_id>("lock_file_fd").first;
-
-      int fd;
-      //If not found schedule a creation
-      if(!pserial_id){
-         fd = GMemNotPresent;
-      }
-      //Else get it
-      else{
-         fd = pserial_id->fd;
-      }
-      //If we need to create a new one, do it
-      if(fd == GMemNotPresent){
-         std::string lck_str;
-         //Create a unique current pid based lock file path
-         create_and_get_singleton_lock_file_path(lck_str);
-         //Open or create and lock file
-         int fd = intermodule_singleton_helpers::open_or_create_and_lock_file(lck_str.c_str());
-         //If failed, write a bad file descriptor to notify other modules that
-         //something was wrong and unlink shared memory. Mark the function object
-         //to tell caller to retry with another shared memory
-         if(fd < 0){
-            this->register_lock_file(GMemMarkToBeRemoved);
-            std::string s;
-            get_shm_name(s);
-            shared_memory_object::remove(s.c_str());
-            retry_with_new_shm = true;
-         }
-         //If successful, register the file descriptor
-         else{
-            this->register_lock_file(fd);
-         }
-      }
-      //If the fd was invalid (maybe a previous try failed) notify caller that
-      //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;
-      }
-      //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,
-      //then it's an old shm from an old process with the same pid.
-      //If that's the case, mark it as invalid
-      else if(!is_valid_fd(fd) ||
-            !is_normal_file(fd) ||
-            0 != get_size(fd) ||
-            !compare_file_serial(fd, *pserial_id)){
-         pserial_id->fd = GMemMarkToBeRemoved;
-         std::string s;
-         get_shm_name(s);
-         shared_memory_object::remove(s.c_str());
-         retry_with_new_shm = true;
-      }
-      else{
-         //If the lock file is ok, increment reference count of
-         //attached modules to shared memory
-         atomic_inc32(&pserial_id->modules_attached_to_gmem_count);
-      }
-   }
-
-   private:
-   locking_file_serial_id * register_lock_file(int fd)
-   {
-      locking_file_serial_id *pinfo = mshm.template construct<locking_file_serial_id>("lock_file_fd")();
-      fill_file_serial_id(fd, *pinfo);
-      return pinfo;
-   }
-
-   public:
-   ManagedShMem &mshm;
-   bool retry_with_new_shm;
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<>
-struct lock_file_logic<windows_managed_global_memory>
-{
-   lock_file_logic(windows_managed_global_memory &)
-      : retry_with_new_shm(false)
-   {}
-
-   void operator()(void){}
-   const bool retry_with_new_shm;
-};
-
-#endif
-
-}  //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 reference counted shared memory
-//to be used by all instances
-
-template<class ManagedShMem>
-class intermodule_singleton_common
-{
-   public:
-   typedef void*(singleton_constructor_t)(ManagedShMem &);
-   typedef void (singleton_destructor_t)(void *, ManagedShMem &);
-
-   static const ::boost::uint32_t Uninitialized       = 0u;
-   static const ::boost::uint32_t Initializing        = 1u;
-   static const ::boost::uint32_t Initialized         = 2u;
-   static const ::boost::uint32_t Broken              = 3u;
-
-   static void finalize_singleton_logic(void *ptr, singleton_destructor_t destructor)
-   {
-      if(ptr)
-         destructor(ptr, get_shm());
-      //If this is the last singleton of this module
-      //apply shm 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();
-      }
-   }
-
-   static void initialize_singleton_logic
-      (void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_constructor_t ini_func);
-
-   private:
-   static ManagedShMem &get_shm()
-   {
-      return *static_cast<ManagedShMem *>(static_cast<void *>(&mem_holder.shm_mem));
-   }
-
-   static void initialize_shm();
-   static void destroy_shm();
-   //Static data, zero-initalized without any dependencies
-   //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
-   static volatile boost::uint32_t this_module_shm_initialized;
-   static struct mem_holder_t
-   {
-      ::boost::detail::max_align aligner;
-      char shm_mem [sizeof(ManagedShMem)];
-   } mem_holder;
-};
-
-template<class ManagedShMem>
-volatile boost::uint32_t intermodule_singleton_common<ManagedShMem>::this_module_singleton_count;
-
-template<class ManagedShMem>
-volatile boost::uint32_t intermodule_singleton_common<ManagedShMem>::this_module_shm_initialized;
-
-template<class ManagedShMem>
-typename intermodule_singleton_common<ManagedShMem>::mem_holder_t
-   intermodule_singleton_common<ManagedShMem>::mem_holder;
-
-template<class ManagedShMem>
-void intermodule_singleton_common<ManagedShMem>::initialize_shm()
-{
-   //Obtain unique shm name and size
-   std::string s;
-   while(1){
-      //Try to pass shm state to initializing
-      ::boost::uint32_t tmp = atomic_cas32(&this_module_shm_initialized, Initializing, Uninitialized);
-      if(tmp >= Initialized){
-         break;
-      }
-      //If some other thread is doing the work wait
-      else if(tmp == Initializing){
-         thread_yield();
-      }
-      else{ //(tmp == Uninitialized)
-         //If not initialized try it again?
-         try{
-            //Remove old shared memory from the system
-            intermodule_singleton_helpers::managed_sh_dependant<ManagedShMem>::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())ManagedShMem(open_or_create, ShmName, ShmSize);
-            //Use shared memory internal lock to initialize the lock file
-            //that will mark this gmem as "in use".
-            intermodule_singleton_helpers::lock_file_logic<ManagedShMem> f(get_shm());
-            //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().~ManagedShMem();
-               atomic_write32(&this_module_shm_initialized, Uninitialized);
-            }
-            else{
-               //Locking succeeded, so this shared memory module-instance is ready
-               atomic_write32(&this_module_shm_initialized, Initialized);
-               break;
-            }
-         }
-         catch(...){
-            //
-            throw;
-         }
-      }
-   }
-}
-
-template<class ManagedShMem>
-struct unlink_shmlogic
-{
-   unlink_shmlogic(ManagedShMem &mshm)
-      : mshm_(mshm)
-   {  mshm.atomic_func(*this);  }
-   void operator()()
-   {
-      intermodule_singleton_helpers::locking_file_serial_id *pserial_id =
-         mshm_.template find<intermodule_singleton_helpers::locking_file_serial_id>
-            ("lock_file_fd").first;
-      BOOST_ASSERT(0 != pserial_id);
-      if(1 == atomic_dec32(&pserial_id->modules_attached_to_gmem_count)){
-         int fd = pserial_id->fd;
-         if(fd > 0){
-            pserial_id->fd = intermodule_singleton_helpers::GMemMarkToBeRemoved;
-            std::string s;
-            intermodule_singleton_helpers::create_and_get_singleton_lock_file_path(s);
-            delete_file(s.c_str());
-            intermodule_singleton_helpers::close_lock_file(fd);
-            intermodule_singleton_helpers::get_shm_name(s);
-            shared_memory_object::remove(s.c_str());
-         }
-      }
-   }
-   ManagedShMem &mshm_;
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<>
-struct unlink_shmlogic<windows_managed_global_memory>
-{
-   unlink_shmlogic(windows_managed_global_memory &)
-   {}
-   void operator()(){}
-};
-
-#endif
-
-
-template<class ManagedShMem>
-void intermodule_singleton_common<ManagedShMem>::destroy_shm()
-{
-   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
-      unlink_shmlogic<ManagedShMem> f(get_shm());
-      (get_shm()).~ManagedShMem();
-      atomic_write32(&this_module_shm_initialized, Uninitialized);
-      //Do some cleanup for other processes old gmem instances
-      intermodule_singleton_helpers::managed_sh_dependant<ManagedShMem>::remove_old_gmem();
-   }
-}
-
-//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,
-//initializing the passed pointer to that unique instance.
-//
-//We have two concurrency types here. a)the shared memory/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.
-//
-//All static variables declared here are shared between inside a module
-//so atomic operations will synchronize only threads of the same module.
-template<class ManagedShMem>
-void intermodule_singleton_common<ManagedShMem>::initialize_singleton_logic
-   (void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_constructor_t constructor)
-{
-   //If current module is not initialized enter to lock free logic
-   if(atomic_read32(&this_module_singleton_initialized) != Initialized){
-      //Now a single thread of the module will succeed in this CAS.
-      //trying to pass from Uninitialized to Initializing
-      ::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
-      if(previous_module_singleton_initialized == Uninitialized){
-         try{
-            //Now initialize shm, this function solves concurrency issues
-            //between threads of several modules
-            initialize_shm();
-            //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
-            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);
-            //Assign the singleton address to the module-local pointer
-            ptr = tmp;
-            //Memory barrier inserted, all previous operations should complete
-            //before this one. Now marked as initialized
-            atomic_inc32(&this_module_singleton_initialized);
-         }
-         catch(...){
-            //Mark singleton failed to initialize
-            atomic_write32(&this_module_singleton_initialized, Broken);
-            throw;
-         }
-      }
-      //If previous state was initializing, this means that another winner thread is
-      //trying to initialize the singleton. Just wait until completes its work.
-      else if(previous_module_singleton_initialized == Initializing){
-         while(1){
-            previous_module_singleton_initialized = atomic_read32(&this_module_singleton_initialized);
-            if(previous_module_singleton_initialized >= Initialized){
-               //Already initialized, or exception thrown by initializer thread
-               break;
-            }
-            else if(previous_module_singleton_initialized == Initializing){
-               thread_yield();
-            }
-            else{
-               //This can't be happening!
-               BOOST_ASSERT(0);
-            }
-         }
-      }
-      else if(previous_module_singleton_initialized == Initialized){
-         //Nothing to do here, the singleton is ready
-      }
-      //If previous state was greater than initialized, then memory is broken
-      //trying to initialize the singleton.
-      else{//(previous_module_singleton_initialized > Initialized)
-         throw interprocess_exception("boost::interprocess::intermodule_singleton initialization failed");
-      }
-   }
-   BOOST_ASSERT(ptr != 0);
-}
-
-//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, class ManagedShMem>
-class intermodule_singleton_impl
-{
-   public:
-   static C& get()   //Let's make inlining easy
-   {
-      if(!this_module_singleton_ptr){
-         if(lifetime.dummy_function())  //This forces lifetime instantiation, for reference counted destruction
-            intermodule_singleton_common<ManagedShMem>::initialize_singleton_logic
-               (this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor);
-      }
-      return *static_cast<C*>(this_module_singleton_ptr);
-   }
-
-   private:
-
-   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;
-   };
-
-   //These statics will be zero-initialized without any constructor call dependency
-   //this_module_singleton_ptr will be a module-local pointer to the singleton
-   static void*                      this_module_singleton_ptr;
-   //this_module_singleton_count will be used to synchronize threads of the same module
-   //for access to a singleton instance, and to flag the state of the
-   //singleton.
-   static volatile boost::uint32_t   this_module_singleton_initialized;
-
-   //This class destructor will trigger singleton destruction
-   struct lifetime_type_lazy
-   {
-      bool dummy_function()
-      {  return m_dummy == 0; }
-
-      ~lifetime_type_lazy()
-      {
-         intermodule_singleton_common<ManagedShMem>::finalize_singleton_logic
-            (this_module_singleton_ptr, singleton_destructor);
-      }
-      //Dummy volatile so that the compiler can't resolve its value at compile-time
-      //and can't avoid lifetime_type instantiation if dummy_function() is called.
-      static volatile int m_dummy;
-   };
-
-   struct lifetime_type_static
-      : public lifetime_type_lazy
-   {
-      lifetime_type_static()
-      {
-         intermodule_singleton_common<ManagedShMem>::initialize_singleton_logic
-            (this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor);
-      }
-   };
-
-   typedef typename if_c
-      <LazyInit, lifetime_type_lazy, lifetime_type_static>::type lifetime_type;
-
-   static lifetime_type lifetime;
-
-   //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.
-   //If singleton constructor throws, the exception is propagated
-   struct init_atomic_func
-   {
-      init_atomic_func(ManagedShMem &m)
-         : mshm(m)
-      {}
-
-      void operator()()
-      {
-         ref_count_ptr *rcount = mshm.template find<ref_count_ptr>(unique_instance).first;
-         if(!rcount){
-            C *p = new C();
-            try{
-               rcount = mshm.template construct<ref_count_ptr>(unique_instance)(p, 0u);
-            }
-            catch(...){
-               delete p;
-               throw;
-            }
-         }
-         atomic_inc32(&rcount->singleton_ref_count);
-         ret_ptr = rcount->ptr;
-      }
-      ManagedShMem &mshm;
-      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
-   struct fini_atomic_func
-   {
-      fini_atomic_func(ManagedShMem &m)
-         : mshm(m)
-      {}
-
-      void operator()()
-      {
-         ref_count_ptr *rcount = mshm.template find<ref_count_ptr>(unique_instance).first;
-            //The object must exist
-         BOOST_ASSERT(rcount);
-         //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);
-            (void)destroyed;  BOOST_ASSERT(destroyed == true);
-         }
-      }
-      ManagedShMem &mshm;
-      void *ret_ptr;
-   };
-
-   //A wrapper to execute init_atomic_func
-   static void *singleton_constructor(ManagedShMem &mshm)
-   {
-      init_atomic_func f(mshm);
-      mshm.atomic_func(f);
-      return f.ret_ptr;
-   }
-
-   //A wrapper to execute fini_atomic_func
-   static void singleton_destructor(void *p, ManagedShMem &mshm)
-   {  (void)p;
-      fini_atomic_func f(mshm);
-      mshm.atomic_func(f);
-   }
-};
-
-template <typename C, bool L, class ManagedShMem>
-volatile int intermodule_singleton_impl<C, L, ManagedShMem>::lifetime_type_lazy::m_dummy = 0;
-
-//These will be zero-initialized by the loader
-template <typename C, bool L, class ManagedShMem>
-void *intermodule_singleton_impl<C, L, ManagedShMem>::this_module_singleton_ptr = 0;
-
-template <typename C, bool L, class ManagedShMem>
-volatile boost::uint32_t intermodule_singleton_impl<C, L, ManagedShMem>::this_module_singleton_initialized = 0;
-
-template <typename C, bool L, class ManagedShMem>
-typename intermodule_singleton_impl<C, L, ManagedShMem>::lifetime_type
-   intermodule_singleton_impl<C, L, ManagedShMem>::lifetime;
-
-template<typename C, bool LazyInit = false>
-class portable_intermodule_singleton
-   : public intermodule_singleton_impl<C, LazyInit, managed_global_memory>
-{};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<typename C, bool LazyInit = false>
-class windows_intermodule_singleton
-   : public intermodule_singleton_impl
-      < C
-      , LazyInit
-      , windows_managed_global_memory
-      >
-{};
-
-#endif
-
 //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.
@@ -1174,7 +39,6 @@
    #endif
 {};
 
-
 }  //namespace ipcdetail{
 }  //namespace interprocess{
 }  //namespace boost{
Added: trunk/boost/interprocess/detail/intermodule_singleton_common.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/intermodule_singleton_common.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,439 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2011. 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_INTERMODULE_SINGLETON_COMMON_HPP
+#define BOOST_INTERPROCESS_INTERMODULE_SINGLETON_COMMON_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/detail/atomic.hpp>
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+#include <boost/type_traits/type_with_alignment.hpp>
+#include <boost/assert.hpp>
+#include <cstddef>
+#include <cstdio>
+#include <cstring>
+#include <string>
+#include <sstream>
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail{
+
+namespace intermodule_singleton_helpers {
+
+inline void get_pid_creation_time_str(std::string &s)
+{
+   std::stringstream stream;
+   stream << get_current_process_id() << '_';
+   stream.precision(6);
+   stream << std::fixed << get_current_process_creation_time();
+   s = stream.str();
+}
+
+inline const char *get_shm_base_name()
+{  return "bip.gmem.shm.";  }
+
+inline void get_shm_name(std::string &shm_name)
+{
+   get_pid_creation_time_str(shm_name);
+   shm_name.insert(0, get_shm_base_name());
+}
+
+inline std::size_t get_shm_size()
+{  return 65536;  }
+
+template<class ManagedGlobalMemory>
+struct managed_sh_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 reference counted shared memory
+//to be used by all instances
+
+template<class ManagedGlobalMemory>
+class intermodule_singleton_common
+{
+   public:
+   typedef void*(singleton_constructor_t)(ManagedGlobalMemory &);
+   typedef void (singleton_destructor_t)(void *, ManagedGlobalMemory &);
+
+   static const ::boost::uint32_t Uninitialized       = 0u;
+   static const ::boost::uint32_t Initializing        = 1u;
+   static const ::boost::uint32_t Initialized         = 2u;
+   static const ::boost::uint32_t Broken              = 3u;
+
+   static void finalize_singleton_logic(void *ptr, singleton_destructor_t destructor)
+   {
+      //Protect destruction against lazy singletons not initialized in this execution
+      if(ptr){
+         destructor(ptr, get_shm());
+         //If this is the last singleton of this module
+         //apply shm 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();
+         }
+      }
+   }
+
+   static void initialize_singleton_logic
+      (void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_constructor_t ini_func);
+
+   private:
+   static ManagedGlobalMemory &get_shm()
+   {
+      return *static_cast<ManagedGlobalMemory *>(static_cast<void *>(&mem_holder.shm_mem));
+   }
+
+   static void initialize_shm();
+   static void destroy_shm();
+   //Static data, zero-initalized without any dependencies
+   //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
+   static volatile boost::uint32_t this_module_shm_initialized;
+   static struct mem_holder_t
+   {
+      ::boost::detail::max_align aligner;
+      char shm_mem [sizeof(ManagedGlobalMemory)];
+   } mem_holder;
+};
+
+template<class ManagedGlobalMemory>
+volatile boost::uint32_t intermodule_singleton_common<ManagedGlobalMemory>::this_module_singleton_count;
+
+template<class ManagedGlobalMemory>
+volatile boost::uint32_t intermodule_singleton_common<ManagedGlobalMemory>::this_module_shm_initialized;
+
+template<class ManagedGlobalMemory>
+typename intermodule_singleton_common<ManagedGlobalMemory>::mem_holder_t
+   intermodule_singleton_common<ManagedGlobalMemory>::mem_holder;
+
+template<class ManagedGlobalMemory>
+void intermodule_singleton_common<ManagedGlobalMemory>::initialize_shm()
+{
+   //Obtain unique shm name and size
+   std::string s;
+   while(1){
+      //Try to pass shm state to initializing
+      ::boost::uint32_t tmp = atomic_cas32(&this_module_shm_initialized, Initializing, Uninitialized);
+      if(tmp >= Initialized){
+         break;
+      }
+      //If some other thread is doing the work wait
+      else if(tmp == Initializing){
+         thread_yield();
+      }
+      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
+            //that will mark this gmem as "in use".
+            typename intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::
+               lock_file_logic f(get_shm());
+            //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, Uninitialized);
+            }
+            else{
+               //Locking succeeded, so this shared memory module-instance is ready
+               atomic_write32(&this_module_shm_initialized, Initialized);
+               break;
+            }
+         }
+         catch(...){
+            //
+            throw;
+         }
+      }
+   }
+}
+
+template<class ManagedGlobalMemory>
+void intermodule_singleton_common<ManagedGlobalMemory>::destroy_shm()
+{
+   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, Uninitialized);
+      //Do some cleanup for other processes old gmem instances
+      intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::remove_old_gmem();
+   }
+}
+
+//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,
+//initializing the passed pointer to that unique instance.
+//
+//We have two concurrency types here. a)the shared memory/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.
+//
+//All static variables declared here are shared between inside a module
+//so atomic operations will synchronize only threads of the same module.
+template<class ManagedGlobalMemory>
+void intermodule_singleton_common<ManagedGlobalMemory>::initialize_singleton_logic
+   (void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_constructor_t constructor)
+{
+   //If current module is not initialized enter to lock free logic
+   if(atomic_read32(&this_module_singleton_initialized) != Initialized){
+      //Now a single thread of the module will succeed in this CAS.
+      //trying to pass from Uninitialized to Initializing
+      ::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
+      if(previous_module_singleton_initialized == Uninitialized){
+         try{
+            //Now initialize shm, this function solves concurrency issues
+            //between threads of several modules
+            initialize_shm();
+            //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
+            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);
+            //Assign the singleton address to the module-local pointer
+            ptr = tmp;
+            //Memory barrier inserted, all previous operations should complete
+            //before this one. Now marked as initialized
+            atomic_inc32(&this_module_singleton_initialized);
+         }
+         catch(...){
+            //Mark singleton failed to initialize
+            atomic_write32(&this_module_singleton_initialized, Broken);
+            throw;
+         }
+      }
+      //If previous state was initializing, this means that another winner thread is
+      //trying to initialize the singleton. Just wait until completes its work.
+      else if(previous_module_singleton_initialized == Initializing){
+         while(1){
+            previous_module_singleton_initialized = atomic_read32(&this_module_singleton_initialized);
+            if(previous_module_singleton_initialized >= Initialized){
+               //Already initialized, or exception thrown by initializer thread
+               break;
+            }
+            else if(previous_module_singleton_initialized == Initializing){
+               thread_yield();
+            }
+            else{
+               //This can't be happening!
+               BOOST_ASSERT(0);
+            }
+         }
+      }
+      else if(previous_module_singleton_initialized == Initialized){
+         //Nothing to do here, the singleton is ready
+      }
+      //If previous state was greater than initialized, then memory is broken
+      //trying to initialize the singleton.
+      else{//(previous_module_singleton_initialized > Initialized)
+         throw interprocess_exception("boost::interprocess::intermodule_singleton initialization failed");
+      }
+   }
+   BOOST_ASSERT(ptr != 0);
+}
+
+//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, class ManagedGlobalMemory>
+class intermodule_singleton_impl
+{
+   public:
+   static C& get()   //Let's make inlining easy
+   {
+      if(!this_module_singleton_ptr){
+         if(lifetime.dummy_function())  //This forces lifetime instantiation, for reference counted destruction
+            intermodule_singleton_common<ManagedGlobalMemory>::initialize_singleton_logic
+               (this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor);
+      }
+      return *static_cast<C*>(this_module_singleton_ptr);
+   }
+
+   private:
+
+   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;
+   };
+
+   //These statics will be zero-initialized without any constructor call dependency
+   //this_module_singleton_ptr will be a module-local pointer to the singleton
+   static void*                      this_module_singleton_ptr;
+   //this_module_singleton_count will be used to synchronize threads of the same module
+   //for access to a singleton instance, and to flag the state of the
+   //singleton.
+   static volatile boost::uint32_t   this_module_singleton_initialized;
+
+   //This class destructor will trigger singleton destruction
+   struct lifetime_type_lazy
+   {
+      bool dummy_function()
+      {  return m_dummy == 0; }
+
+      ~lifetime_type_lazy()
+      {
+         intermodule_singleton_common<ManagedGlobalMemory>::finalize_singleton_logic
+            (this_module_singleton_ptr, singleton_destructor);
+      }
+      //Dummy volatile so that the compiler can't resolve its value at compile-time
+      //and can't avoid lifetime_type instantiation if dummy_function() is called.
+      static volatile int m_dummy;
+   };
+
+   struct lifetime_type_static
+      : public lifetime_type_lazy
+   {
+      lifetime_type_static()
+      {
+         intermodule_singleton_common<ManagedGlobalMemory>::initialize_singleton_logic
+            (this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor);
+      }
+   };
+
+   typedef typename if_c
+      <LazyInit, lifetime_type_lazy, lifetime_type_static>::type lifetime_type;
+
+   static lifetime_type lifetime;
+
+   //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.
+   //If singleton constructor throws, the exception is propagated
+   struct init_atomic_func
+   {
+      init_atomic_func(ManagedGlobalMemory &m)
+         : mshm(m)
+      {}
+
+      void operator()()
+      {
+         ref_count_ptr *rcount = mshm.template find<ref_count_ptr>(unique_instance).first;
+         if(!rcount){
+            C *p = new C();
+            try{
+               rcount = mshm.template construct<ref_count_ptr>(unique_instance)(p, 0u);
+            }
+            catch(...){
+               delete p;
+               throw;
+            }
+         }
+         atomic_inc32(&rcount->singleton_ref_count);
+         ret_ptr = rcount->ptr;
+      }
+      ManagedGlobalMemory &mshm;
+      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
+   struct fini_atomic_func
+   {
+      fini_atomic_func(ManagedGlobalMemory &m)
+         : mshm(m)
+      {}
+
+      void operator()()
+      {
+         ref_count_ptr *rcount = mshm.template find<ref_count_ptr>(unique_instance).first;
+            //The object must exist
+         BOOST_ASSERT(rcount);
+         //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);
+            (void)destroyed;  BOOST_ASSERT(destroyed == true);
+         }
+      }
+      ManagedGlobalMemory &mshm;
+      void *ret_ptr;
+   };
+
+   //A wrapper to execute init_atomic_func
+   static void *singleton_constructor(ManagedGlobalMemory &mshm)
+   {
+      init_atomic_func f(mshm);
+      mshm.atomic_func(f);
+      return f.ret_ptr;
+   }
+
+   //A wrapper to execute fini_atomic_func
+   static void singleton_destructor(void *p, ManagedGlobalMemory &mshm)
+   {  (void)p;
+      fini_atomic_func f(mshm);
+      mshm.atomic_func(f);
+   }
+};
+
+template <typename C, bool L, class ManagedGlobalMemory>
+volatile int intermodule_singleton_impl<C, L, ManagedGlobalMemory>::lifetime_type_lazy::m_dummy = 0;
+
+//These will be zero-initialized by the loader
+template <typename C, bool L, class ManagedGlobalMemory>
+void *intermodule_singleton_impl<C, L, ManagedGlobalMemory>::this_module_singleton_ptr = 0;
+
+template <typename C, bool L, class ManagedGlobalMemory>
+volatile boost::uint32_t intermodule_singleton_impl<C, L, ManagedGlobalMemory>::this_module_singleton_initialized = 0;
+
+template <typename C, bool L, class ManagedGlobalMemory>
+typename intermodule_singleton_impl<C, L, ManagedGlobalMemory>::lifetime_type
+   intermodule_singleton_impl<C, L, ManagedGlobalMemory>::lifetime;
+
+}  //namespace ipcdetail{
+}  //namespace interprocess{
+}  //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_INTERPROCESS_INTERMODULE_SINGLETON_COMMON_HPP
Added: trunk/boost/interprocess/detail/managed_global_memory.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/managed_global_memory.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,115 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-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_BASIC_GLOBAL_MEMORY_HPP
+#define BOOST_INTERPROCESS_BASIC_GLOBAL_MEMORY_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/offset_ptr.hpp>
+#include <boost/interprocess/sync/spin/mutex.hpp>
+#include <boost/interprocess/sync/spin/recursive_mutex.hpp>
+#include <boost/interprocess/detail/managed_memory_impl.hpp>
+#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>  
+#include <boost/interprocess/indexes/iset_index.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/permissions.hpp>
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail{
+
+struct intermodule_singleton_mutex_family
+{
+   typedef boost::interprocess::ipcdetail::spin_mutex              mutex_type;
+   typedef boost::interprocess::ipcdetail::spin_recursive_mutex    recursive_mutex_type;
+};
+
+struct intermodule_types
+{
+   //We must use offset_ptr since a loaded DLL can map the singleton holder shared memory
+   //at a different address than other DLLs or the main executable
+   typedef rbtree_best_fit<intermodule_singleton_mutex_family, offset_ptr<void> > mem_algo;
+   template<class Device, bool FileBased>
+   struct open_or_create
+   {
+      typedef managed_open_or_create_impl
+            <Device, mem_algo::Alignment, FileBased> type;
+   };
+};
+
+//we must implement our own managed shared memory to avoid circular dependencies
+template<class Device, bool FileBased>
+class basic_managed_global_memory 
+   : public basic_managed_memory_impl
+      < char
+      , intermodule_types::mem_algo
+      , iset_index
+      , intermodule_types::open_or_create<Device, FileBased>::type::ManagedOpenOrCreateUserOffset
+      >
+   , private intermodule_types::open_or_create<Device, FileBased>::type
+{
+   /// @cond
+   typedef typename intermodule_types::template open_or_create<Device, FileBased>::type base2_t;
+
+   typedef basic_managed_memory_impl
+      < char
+      , intermodule_types::mem_algo
+      , iset_index
+      , base2_t::ManagedOpenOrCreateUserOffset
+      > base_t;
+
+   typedef create_open_func<base_t>        create_open_func_t;
+
+   basic_managed_global_memory *get_this_pointer()
+   {  return this;   }
+
+   public:
+   typedef typename base_t::size_type              size_type;
+
+   private:
+   typedef typename base_t::char_ptr_holder_t   char_ptr_holder_t;
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_managed_global_memory)
+   /// @endcond
+
+   public: //functions
+
+   basic_managed_global_memory (open_or_create_t open_or_create,
+                              const char *name, size_type size, 
+                              const void *addr = 0, const permissions& perm = permissions())
+      : base_t()
+      , base2_t(open_or_create, name, size, read_write, addr, 
+                create_open_func_t(get_this_pointer(), 
+                DoOpenOrCreate), perm)
+   {}
+
+   basic_managed_global_memory (open_only_t open_only, const char* name, 
+                                const void *addr = 0)
+      : base_t()
+      , base2_t(open_only, name, read_write, addr, 
+                create_open_func_t(get_this_pointer(), 
+                DoOpen))
+   {}
+};
+
+
+}  //namespace ipcdetail{
+}  //namespace interprocess{
+}  //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_INTERPROCESS_BASIC_GLOBAL_MEMORY_HPP
Modified: trunk/boost/interprocess/detail/os_file_functions.hpp
==============================================================================
--- trunk/boost/interprocess/detail/os_file_functions.hpp	(original)
+++ trunk/boost/interprocess/detail/os_file_functions.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -140,7 +140,7 @@
    if(offset_t(size) > filesize){
       if(!winapi::set_file_pointer_ex(hnd, filesize, 0, winapi::file_begin)){
          return false;
-      }      
+      }
       //We will write zeros in the end of the file
       //since set_end_of_file does not guarantee this
       for(std::size_t remaining = size - filesize, write_size = 0
@@ -191,7 +191,7 @@
 inline bool acquire_file_lock(file_handle_t hnd)
 {  
    static winapi::interprocess_overlapped overlapped;
-   const unsigned long len = 0xffffffff;
+   const unsigned long len = ~((unsigned long)(0u));
 //   winapi::interprocess_overlapped overlapped;
 //   std::memset(&overlapped, 0, sizeof(overlapped));
    return winapi::lock_file_ex
@@ -200,7 +200,7 @@
 
 inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
 {  
-   const unsigned long len = 0xffffffff;
+   const unsigned long len = ~((unsigned long)(0u));
    winapi::interprocess_overlapped overlapped;
    std::memset(&overlapped, 0, sizeof(overlapped));
    if(!winapi::lock_file_ex
@@ -215,7 +215,7 @@
 
 inline bool release_file_lock(file_handle_t hnd)
 {  
-   const unsigned long len = 0xffffffff;
+   const unsigned long len = ~((unsigned long)(0u));
    winapi::interprocess_overlapped overlapped;
    std::memset(&overlapped, 0, sizeof(overlapped));
    return winapi::unlock_file_ex(hnd, 0, len, len, &overlapped);
@@ -223,7 +223,7 @@
 
 inline bool acquire_file_lock_sharable(file_handle_t hnd)
 {  
-   const unsigned long len = 0xffffffff;
+   const unsigned long len = ~((unsigned long)(0u));
    winapi::interprocess_overlapped overlapped;
    std::memset(&overlapped, 0, sizeof(overlapped));
    return winapi::lock_file_ex(hnd, 0, 0, len, len, &overlapped);
@@ -231,7 +231,7 @@
 
 inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
 {  
-   const unsigned long len = 0xffffffff;
+   const unsigned long len = ~((unsigned long)(0u));
    winapi::interprocess_overlapped overlapped;
    std::memset(&overlapped, 0, sizeof(overlapped));
    if(!winapi::lock_file_ex
Modified: trunk/boost/interprocess/detail/pointer_type.hpp
==============================================================================
--- trunk/boost/interprocess/detail/pointer_type.hpp	(original)
+++ trunk/boost/interprocess/detail/pointer_type.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -61,7 +61,7 @@
 struct pointer_type
 {
     typedef typename pointer_type_imp::pointer_type<T,
-        typename ipcdetail::remove_reference<D>::type>::type type;
+        typename remove_reference<D>::type>::type type;
 };
 
 }  //namespace ipcdetail {
Added: trunk/boost/interprocess/detail/portable_intermodule_singleton.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/portable_intermodule_singleton.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,321 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2011. 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_PORTABLE_INTERMODULE_SINGLETON_HPP
+#define BOOST_INTERPROCESS_PORTABLE_INTERMODULE_SINGLETON_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/detail/managed_global_memory.hpp>
+#include <boost/interprocess/detail/intermodule_singleton_common.hpp>
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/detail/atomic.hpp>
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
+#include <boost/interprocess/detail/os_file_functions.hpp>
+#include <boost/interprocess/detail/file_locking_helpers.hpp>
+#include <boost/assert.hpp>
+#include <cstddef>
+#include <cstdio>
+#include <cstring>
+#include <string>
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail{
+
+typedef basic_managed_global_memory<shared_memory_object, true>    managed_global_memory;
+
+namespace intermodule_singleton_helpers {
+
+static void create_tmp_subdir_and_get_pid_based_filepath
+   (const char *subdir_name, const char *file_prefix, OS_process_id_t pid, std::string &s, bool creation_time = false)
+{
+   //Let's create a lock file for each process gmem that will mark if
+   //the process is alive or not
+   create_tmp_and_clean_old(s);
+   s += "/";
+   s += subdir_name;
+   if(!open_or_create_directory(s.c_str())){
+      throw interprocess_exception(error_info(system_error_code()));
+   }
+   s += "/";
+   s += file_prefix;
+   if(creation_time){
+      std::string sstamp;   
+      get_pid_creation_time_str(sstamp);
+      s += sstamp;
+   }
+   else{
+      pid_str_t pid_str;
+      get_pid_str(pid_str, pid);
+      s += pid_str;
+   }
+}
+
+static bool check_if_filename_complies_with_pid
+   (const char *filename, const char *prefix, OS_process_id_t pid, std::string &file_suffix, bool creation_time = false)
+{
+   //Check if filename complies with lock file name pattern
+   std::string fname(filename);
+   std::string fprefix(prefix);
+   if(fname.size() <= fprefix.size()){
+      return false;
+   }
+   fname.resize(fprefix.size());
+   if(fname != fprefix){
+      return false;
+   }
+
+   //If not our lock file, delete it if we can lock it
+   fname = filename;
+   fname.erase(0, fprefix.size());
+   pid_str_t pid_str;
+   get_pid_str(pid_str, pid);
+   file_suffix = pid_str;
+   if(creation_time){
+      std::size_t p = fname.find('_');
+      if (p == std::string::npos){
+         return false;
+      }
+      std::string save_suffix(fname);
+      fname.erase(p);
+      fname.swap(file_suffix);
+      bool ret = (file_suffix == fname);
+      file_suffix.swap(save_suffix);
+      return ret;
+   }
+   else{
+      fname.swap(file_suffix);
+      return (file_suffix == fname);
+   }
+}
+
+template<>
+struct managed_sh_dependant<managed_global_memory>
+{
+   private:
+   static const int GMemMarkToBeRemoved = -1;
+   static const int GMemNotPresent      = -2;
+
+   static const char *get_lock_file_subdir_name()
+   {  return "gmem";  }
+
+   static const char *get_lock_file_base_name()
+   {  return "lck";  }
+
+   static void create_and_get_singleton_lock_file_path(std::string &s)
+   {
+      create_tmp_subdir_and_get_pid_based_filepath
+         (get_lock_file_subdir_name(), get_lock_file_base_name(), get_current_process_id(), s, true);
+   }
+
+   struct gmem_erase_func
+   {
+      gmem_erase_func(const char *shm_name, const char *singleton_lock_file_path, managed_global_memory & shm)
+         :shm_name_(shm_name), singleton_lock_file_path_(singleton_lock_file_path), shm_(shm)
+      {}
+
+      void operator()()
+      {
+         locking_file_serial_id *pserial_id = shm_.find<locking_file_serial_id>("lock_file_fd").first;
+         if(pserial_id){
+            pserial_id->fd = GMemMarkToBeRemoved;
+         }
+         delete_file(singleton_lock_file_path_);
+         shared_memory_object::remove(shm_name_);
+      }
+      
+      const char * const shm_name_;
+      const char * const singleton_lock_file_path_;
+      managed_global_memory & shm_;
+   };
+
+   public:
+   //This function applies shared memory erasure logic based on the passed lock file.
+   static void apply_gmem_erase_logic(const char *filepath, const char *filename)
+   {
+      int fd = GMemMarkToBeRemoved;
+      try{
+         std::string str;
+         //If the filename is current process lock file, then avoid it
+         if(check_if_filename_complies_with_pid
+            (filename, get_lock_file_base_name(), get_current_process_id(), str, true)){
+            return;
+         }
+         //Open and lock the other process' lock file
+         fd = try_open_and_lock_file(filepath);
+         if(fd < 0){
+            return;
+         }
+         //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());
+         try{
+            managed_global_memory shm(open_only, str.c_str());
+            gmem_erase_func func(str.c_str(), filepath, shm);
+            shm.try_atomic_func(func);
+         }
+         catch(interprocess_exception &e){
+            //If shared memory is not found erase the lock file
+            if(e.get_error_code() == not_found_error){
+               delete_file(filepath);
+            }
+         }
+      }
+      catch(...){
+
+      }
+      if(fd >= 0){
+         close_lock_file(fd);
+      }
+   }
+
+   static bool remove_old_gmem()
+   {
+      std::string refcstrRootDirectory;
+      tmp_folder(refcstrRootDirectory);
+      refcstrRootDirectory += "/";
+      refcstrRootDirectory += get_lock_file_subdir_name();
+      return for_each_file_in_dir(refcstrRootDirectory.c_str(), apply_gmem_erase_logic);
+   }
+
+   struct lock_file_logic
+   {
+      lock_file_logic(managed_global_memory &shm)
+         : mshm(shm)
+      {  shm.atomic_func(*this); }
+
+      void operator()(void)
+      {
+         retry_with_new_shm = false;
+
+         //First find the file locking descriptor id
+         locking_file_serial_id *pserial_id =
+            mshm.find<locking_file_serial_id>("lock_file_fd").first;
+
+         int fd;
+         //If not found schedule a creation
+         if(!pserial_id){
+            fd = GMemNotPresent;
+         }
+         //Else get it
+         else{
+            fd = pserial_id->fd;
+         }
+         //If we need to create a new one, do it
+         if(fd == GMemNotPresent){
+            std::string lck_str;
+            //Create a unique current pid based lock file path
+            create_and_get_singleton_lock_file_path(lck_str);
+            //Open or create and lock file
+            int fd = open_or_create_and_lock_file(lck_str.c_str());
+            //If failed, write a bad file descriptor to notify other modules that
+            //something was wrong and unlink shared memory. Mark the function object
+            //to tell caller to retry with another shared memory
+            if(fd < 0){
+               this->register_lock_file(GMemMarkToBeRemoved);
+               std::string s;
+               get_shm_name(s);
+               shared_memory_object::remove(s.c_str());
+               retry_with_new_shm = true;
+            }
+            //If successful, register the file descriptor
+            else{
+               this->register_lock_file(fd);
+            }
+         }
+         //If the fd was invalid (maybe a previous try failed) notify caller that
+         //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;
+         }
+         //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,
+         //then it's an old shm from an old process with the same pid.
+         //If that's the case, mark it as invalid
+         else if(!is_valid_fd(fd) ||
+               !is_normal_file(fd) ||
+               0 != get_size(fd) ||
+               !compare_file_serial(fd, *pserial_id)){
+            pserial_id->fd = GMemMarkToBeRemoved;
+            std::string s;
+            get_shm_name(s);
+            shared_memory_object::remove(s.c_str());
+            retry_with_new_shm = true;
+         }
+         else{
+            //If the lock file is ok, increment reference count of
+            //attached modules to shared memory
+            atomic_inc32(&pserial_id->modules_attached_to_gmem_count);
+         }
+      }
+
+      private:
+      locking_file_serial_id * register_lock_file(int fd)
+      {
+         locking_file_serial_id *pinfo = mshm.construct<locking_file_serial_id>("lock_file_fd")();
+         fill_file_serial_id(fd, *pinfo);
+         return pinfo;
+      }
+
+      public:
+      managed_global_memory &mshm;
+      bool retry_with_new_shm;
+   };
+
+   struct unlink_shmlogic
+   {
+      unlink_shmlogic(managed_global_memory &mshm)
+         : mshm_(mshm)
+      {  mshm.atomic_func(*this);  }
+      void operator()()
+      {
+         locking_file_serial_id *pserial_id =
+            mshm_.find<locking_file_serial_id>
+               ("lock_file_fd").first;
+         BOOST_ASSERT(0 != pserial_id);
+         if(1 == atomic_dec32(&pserial_id->modules_attached_to_gmem_count)){
+            int fd = pserial_id->fd;
+            if(fd > 0){
+               pserial_id->fd = GMemMarkToBeRemoved;
+               std::string s;
+               create_and_get_singleton_lock_file_path(s);
+               delete_file(s.c_str());
+               close_lock_file(fd);
+               intermodule_singleton_helpers::get_shm_name(s);
+               shared_memory_object::remove(s.c_str());
+            }
+         }
+      }
+      managed_global_memory &mshm_;
+   };
+};
+
+}  //namespace intermodule_singleton_helpers {
+
+template<typename C, bool LazyInit = false>
+class portable_intermodule_singleton
+   : public intermodule_singleton_impl<C, LazyInit, managed_global_memory>
+{};
+
+}  //namespace ipcdetail{
+}  //namespace interprocess{
+}  //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_INTERPROCESS_PORTABLE_INTERMODULE_SINGLETON_HPP
Modified: trunk/boost/interprocess/detail/preprocessor.hpp
==============================================================================
--- trunk/boost/interprocess/detail/preprocessor.hpp	(original)
+++ trunk/boost/interprocess/detail/preprocessor.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -57,28 +57,30 @@
 
 #ifndef BOOST_NO_RVALUE_REFERENCES
 
-#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+   #if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
 
-#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
-  BOOST_PP_CAT(m_p, n) (BOOST_INTERPROCESS_MOVE_NAMESPACE::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ))           \
-//!
+   #define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data)  \
+      BOOST_PP_CAT(m_p, n) (BOOST_PP_CAT(p, n))          \
+   //!
 
-#else
 
-#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
-  BOOST_PP_CAT(m_p, n) (BOOST_PP_CAT(p, n))           \
-//!
+   #else //#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
 
-#endif
+   #define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
+     BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ))  \
+   //!
 
-#else
-#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
-  BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
-//!
+   #endif   //#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+#else //#ifndef BOOST_NO_RVALUE_REFERENCES
+
+   #define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
+     BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
+   //!
 #endif
 
 #define BOOST_INTERPROCESS_PP_PARAM_INC(z, n, data)   \
-  BOOST_PP_CAT(++m_p, n)                        \
+   BOOST_PP_CAT(++m_p, n)                        \
 //!
 
 #ifndef BOOST_NO_RVALUE_REFERENCES
Modified: trunk/boost/interprocess/detail/robust_emulation.hpp
==============================================================================
--- trunk/boost/interprocess/detail/robust_emulation.hpp	(original)
+++ trunk/boost/interprocess/detail/robust_emulation.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -68,7 +68,7 @@
 
 inline void create_and_get_robust_lock_file_path(std::string &s, OS_process_id_t pid)
 {
-   file_locking_helpers::create_tmp_subdir_and_get_pid_based_filepath
+   intermodule_singleton_helpers::create_tmp_subdir_and_get_pid_based_filepath
       (robust_lock_subdir_path(), robust_lock_prefix(), pid, s);
 }
 
@@ -154,7 +154,7 @@
       {
          std::string pid_str;
          //If the lock file is not our own lock file, then try to do the cleanup
-         if(!file_locking_helpers::check_if_filename_complies_with_pid
+         if(!intermodule_singleton_helpers::check_if_filename_complies_with_pid
             (filename, robust_lock_prefix(), get_current_process_id(), pid_str)){
             remove_if_can_lock_file(filepath);
          }
Modified: trunk/boost/interprocess/detail/tmp_dir_helpers.hpp
==============================================================================
--- trunk/boost/interprocess/detail/tmp_dir_helpers.hpp	(original)
+++ trunk/boost/interprocess/detail/tmp_dir_helpers.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -18,80 +18,87 @@
 #include <boost/interprocess/exceptions.hpp>
 #include <string>
 
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-   //#define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME
-   //#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
-   //#include <boost/interprocess/detail/win32_api.hpp>
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
-   //#include <sys/sysctl.h>
-   //#if defined(CTL_KERN) && defined (KERN_BOOTTIME)
-      //#define BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME
-      //#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
-   //#endif
+#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME) && defined(BOOST_INTERPROCESS_WINDOWS)
+   #include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
 #endif
 
 namespace boost {
 namespace interprocess {
 namespace ipcdetail {
 
-#if defined (BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME)
-inline void get_bootstamp(std::string &s, bool add = false)
-{
-   std::string bootstamp;
-   winapi::get_last_bootup_time(bootstamp);
-   if(add){
-      s += bootstamp;
-   }
-   else{
-      s.swap(bootstamp);
-   }
-}
-#elif defined(BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME)
-inline void get_bootstamp(std::string &s, bool add = false)
-{
-   // FreeBSD specific: sysctl "kern.boottime"
-   int request[2] = { CTL_KERN, KERN_BOOTTIME };
-   struct ::timeval result;
-   std::size_t result_len = sizeof result;
-
-   if (::sysctl (request, 2, &result, &result_len, NULL, 0) < 0)
-      return;
-
-   char bootstamp_str[256];
-
-   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;
-   //32 bit values to allow 32 and 64 bit process IPC
-   boost::uint32_t fields[2] = { boost::uint32_t(result.tv_sec), boost::uint32_t(result.tv_usec) };
-   for(std::size_t field = 0; field != 2; ++field){
-      for(std::size_t i = 0; i != sizeof(fields[0]); ++i){
-         const char *ptr = (const char *)&fields[field];
-         bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
-         bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
+#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
+   #if defined(BOOST_INTERPROCESS_WINDOWS)
+      //This type will initialize the stamp
+      struct windows_bootstamp
+      {
+         windows_bootstamp()
+         {
+            winapi::get_last_bootup_time(stamp);
+         }
+         //Use std::string. Even if this will be constructed in shared memory, all
+         //modules/dlls are from this process so internal raw pointers to heap are always valid
+         std::string stamp;
+      };
+
+      inline void get_bootstamp(std::string &s, bool add = false)
+      {
+         const windows_bootstamp &bootstamp = windows_intermodule_singleton<windows_bootstamp, true>::get();
+         if(add){
+            s += bootstamp.stamp;
+         }
+         else{
+            s = bootstamp.stamp;
+         }
       }
-   }
-   bootstamp_str[char_counter] = 0;
-   if(add){
-      s += bootstamp_str;
-   }
-   else{
-      s = bootstamp_str;
-   }
-}
-#endif
+   #elif defined(BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME)
+      inline void get_bootstamp(std::string &s, bool add = false)
+      {
+         // FreeBSD specific: sysctl "kern.boottime"
+         int request[2] = { CTL_KERN, KERN_BOOTTIME };
+         struct ::timeval result;
+         std::size_t result_len = sizeof result;
+
+         if (::sysctl (request, 2, &result, &result_len, NULL, 0) < 0)
+            return;
+
+         char bootstamp_str[256];
+
+         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;
+         //32 bit values to allow 32 and 64 bit process IPC
+         boost::uint32_t fields[2] = { boost::uint32_t(result.tv_sec), boost::uint32_t(result.tv_usec) };
+         for(std::size_t field = 0; field != 2; ++field){
+            for(std::size_t i = 0; i != sizeof(fields[0]); ++i){
+               const char *ptr = (const char *)&fields[field];
+               bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
+               bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
+            }
+         }
+         bootstamp_str[char_counter] = 0;
+         if(add){
+            s += bootstamp_str;
+         }
+         else{
+            s = bootstamp_str;
+         }
+      }
+   #else
+      #error "BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME defined with no known implementation"
+   #endif
+#endif   //#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
 
 inline void get_tmp_base_dir(std::string &tmp_name)
 {
    #if defined (BOOST_INTERPROCESS_WINDOWS)
-   winapi::get_shared_documents_folder(tmp_name);
-   if(tmp_name.empty() || !winapi::is_directory(tmp_name.c_str())){
-      tmp_name = get_temporary_path();
-   }
+      winapi::get_shared_documents_folder(tmp_name);
+      if(tmp_name.empty() || !winapi::is_directory(tmp_name.c_str())){
+         tmp_name = get_temporary_path();
+      }
    #else
-   tmp_name = get_temporary_path();
+      tmp_name = get_temporary_path();
    #endif
    if(tmp_name.empty()){
       error_info err = system_error_code();
@@ -104,9 +111,9 @@
 inline void tmp_folder(std::string &tmp_name)
 {
    get_tmp_base_dir(tmp_name);
-   #ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
-   tmp_name += "/";
-   get_bootstamp(tmp_name, true);
+   #if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
+      tmp_name += "/";
+      get_bootstamp(tmp_name, true);
    #endif
 }
 
@@ -131,22 +138,22 @@
       }
    }
 
-   #ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
-   tmp_folder(tmp_name);
+   #if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
+      tmp_folder(tmp_name);
 
-   //If fails, check that it's because already exists
-   if(!create_directory(tmp_name.c_str())){
-      error_info info(system_error_code());
-      if(info.get_error_code() != already_exists_error){
-         throw interprocess_exception(info);
+      //If fails, check that it's because already exists
+      if(!create_directory(tmp_name.c_str())){
+         error_info info(system_error_code());
+         if(info.get_error_code() != already_exists_error){
+            throw interprocess_exception(info);
+         }
       }
-   }
-   //Now erase all old directories created in the previous boot sessions
-   std::string subdir = tmp_name;
-   subdir.erase(0, root_tmp_name.size()+1);
-   delete_subdirectories(root_tmp_name, subdir.c_str());
+      //Now erase all old directories created in the previous boot sessions
+      std::string subdir = tmp_name;
+      subdir.erase(0, root_tmp_name.size()+1);
+      delete_subdirectories(root_tmp_name, subdir.c_str());
    #else
-   tmp_name = root_tmp_name;
+      tmp_name = root_tmp_name;
    #endif
 }
 
Modified: trunk/boost/interprocess/detail/win32_api.hpp
==============================================================================
--- trunk/boost/interprocess/detail/win32_api.hpp	(original)
+++ trunk/boost/interprocess/detail/win32_api.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -574,6 +574,12 @@
    void *h_event;
 };
 
+struct interprocess_semaphore_basic_information
+{
+	unsigned int count;		// current semaphore count
+	unsigned int limit;		// max semaphore count
+};
+
 struct interprocess_filetime
 {  
    unsigned long  dwLowDateTime;  
@@ -620,7 +626,7 @@
     unsigned short wProcessorRevision;
 };
 
-struct interprocess_memory_basic_information
+typedef struct _interprocess_memory_basic_information
 {
    void *         BaseAddress;  
    void *         AllocationBase;
@@ -629,7 +635,7 @@
    unsigned long  State;
    unsigned long  Protect;
    unsigned long  Type;
-};
+} interprocess_memory_basic_information;
 
 typedef struct _interprocess_acl
 {
@@ -695,6 +701,10 @@
    file_maximum_information
 };
 
+enum semaphore_information_class {
+   semaphore_basic_information = 0
+};
+
 struct file_name_information_t {
    unsigned long FileNameLength;
    wchar_t FileName[1];
@@ -844,6 +854,7 @@
 extern "C" __declspec(dllimport) int __stdcall LockFileEx(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped);
 extern "C" __declspec(dllimport) int __stdcall UnlockFileEx(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped);
 extern "C" __declspec(dllimport) int __stdcall WriteFile(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped);
+extern "C" __declspec(dllimport) int __stdcall ReadFile(void *hnd, void *buffer, unsigned long bytes_to_read, unsigned long *bytes_read, interprocess_overlapped* overlapped);
 extern "C" __declspec(dllimport) int __stdcall InitializeSecurityDescriptor(interprocess_security_descriptor *pSecurityDescriptor, unsigned long dwRevision);
 extern "C" __declspec(dllimport) int __stdcall SetSecurityDescriptorDacl(interprocess_security_descriptor *pSecurityDescriptor, int bDaclPresent, interprocess_acl *pDacl, int bDaclDefaulted);
 extern "C" __declspec(dllimport) void *__stdcall LoadLibraryA(const char *);
@@ -891,8 +902,9 @@
 //Pointer to functions
 typedef long (__stdcall *NtDeleteFile_t)(object_attributes_t *ObjectAttributes); 
 typedef long (__stdcall *NtSetInformationFile_t)(void *FileHandle, io_status_block_t *IoStatusBlock, void *FileInformation, unsigned long Length, int FileInformationClass ); 
-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 *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 *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*);
@@ -1051,7 +1063,7 @@
       if (error_sharing_violation != get_last_error()){
          return handle;
       }
-      Sleep(error_sharing_violation_sleep_ms);
+      sleep(error_sharing_violation_sleep_ms);
    }
    return invalid_handle_value;
 }
@@ -1101,6 +1113,9 @@
 inline bool write_file(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped)
 {  return 0 != WriteFile(hnd, buffer, bytes_to_write, bytes_written, overlapped);  }
 
+inline bool read_file(void *hnd, void *buffer, unsigned long bytes_to_read, unsigned long *bytes_read, interprocess_overlapped* overlapped)
+{  return 0 != ReadFile(hnd, buffer, bytes_to_read, bytes_read, overlapped);  }
+
 inline bool get_file_information_by_handle(void *hnd, interprocess_by_handle_file_information *info)
 {  return 0 != GetFileInformationByHandle(hnd, info);  }
 
@@ -1176,7 +1191,7 @@
 template<int Dummy>
 struct function_address_holder
 {
-   enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NumFunction };
+   enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NtQuerySemaphore, NumFunction };
    enum { NtDll_dll, NumModule };
 
    private:
@@ -1213,7 +1228,7 @@
    static void *get_address_from_dll(const unsigned int id)
    {
       assert(id < (unsigned int)NumFunction);
-      const char *function[] = { "NtSetInformationFile", "NtQuerySystemInformation", "NtQueryObject" };
+      const char *function[] = { "NtSetInformationFile", "NtQuerySystemInformation", "NtQueryObject", "NtQuerySemaphore" };
       bool compile_check[sizeof(function)/sizeof(function[0]) == NumFunction];
       (void)compile_check;
       return get_proc_address(get_module(NtDll_dll), function[id]);
Added: trunk/boost/interprocess/detail/windows_intermodule_singleton.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/windows_intermodule_singleton.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,81 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2011. 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_INTERMODULE_SINGLETON_HPP
+#define BOOST_INTERPROCESS_WINDOWS_INTERMODULE_SINGLETON_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#if !defined(BOOST_INTERPROCESS_WINDOWS)
+   #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>
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail{
+
+typedef basic_managed_global_memory<windows_shared_memory, false>  windows_managed_global_memory;
+
+namespace intermodule_singleton_helpers {
+
+template<>
+struct managed_sh_dependant<windows_managed_global_memory>
+{
+   static void apply_gmem_erase_logic(const char *, const char *){}
+
+   static bool remove_old_gmem()
+   { return true; }
+
+   struct lock_file_logic
+   {
+      lock_file_logic(windows_managed_global_memory &)
+         : retry_with_new_shm(false)
+      {}
+
+      void operator()(void){}
+      const bool retry_with_new_shm;
+   };
+
+   struct unlink_shmlogic
+   {
+      unlink_shmlogic(windows_managed_global_memory &)
+      {}
+      void operator()(){}
+   };
+};
+
+}  //namespace intermodule_singleton_helpers {
+
+template<typename C, bool LazyInit = false>
+class windows_intermodule_singleton
+   : public intermodule_singleton_impl
+      < C
+      , LazyInit
+      , windows_managed_global_memory
+      >
+{};
+
+}  //namespace ipcdetail{
+}  //namespace interprocess{
+}  //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_INTERPROCESS_WINDOWS_INTERMODULE_SINGLETON_HPP
Modified: trunk/boost/interprocess/detail/workaround.hpp
==============================================================================
--- trunk/boost/interprocess/detail/workaround.hpp	(original)
+++ trunk/boost/interprocess/detail/workaround.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -13,42 +13,33 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 
-#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
-
-#define BOOST_INTERPROCESS_WINDOWS
-
-/*
-#if !defined(_MSC_EXTENSIONS)
-#error "Turn on Microsoft language extensions (_MSC_EXTENSIONS) to be able to call Windows API functions"
-#endif
-*/
-
-#endif
-
-#if !defined(BOOST_INTERPROCESS_WINDOWS)
-
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+   #define BOOST_INTERPROCESS_WINDOWS
+   //#define BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION
+   #define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
+#else 
    #include <unistd.h>
 
-   #if ((_POSIX_THREAD_PROCESS_SHARED - 0) > 0)
-   //Cygwin defines _POSIX_THREAD_PROCESS_SHARED but does not implement it.
-   //Mac Os X >= Leopard defines _POSIX_THREAD_PROCESS_SHARED but does not seems to work.
-   #  if !defined(__CYGWIN__) && !defined(__APPLE__)
-   #  define BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
-   #  endif
+   #if defined(_POSIX_THREAD_PROCESS_SHARED) && ((_POSIX_THREAD_PROCESS_SHARED - 0) > 0)
+      //Cygwin defines _POSIX_THREAD_PROCESS_SHARED but does not implement it.
+      //Mac Os X >= Leopard defines _POSIX_THREAD_PROCESS_SHARED but does not seems to work.
+      #if !defined(__CYGWIN__) && !defined(__APPLE__)
+         #define BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
+      #endif
    #endif
    
-   #if ((_POSIX_BARRIERS - 0) > 0)
-   # define BOOST_INTERPROCESS_POSIX_BARRIERS
-   # endif
-
-   #if ((_POSIX_SEMAPHORES - 0) > 0)
-   # define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
-   #  if defined(__CYGWIN__)
-      #define BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK
-   #  endif
+   #if defined(_POSIX_BARRIERS) && ((_POSIX_BARRIERS - 0) > 0)
+      #define BOOST_INTERPROCESS_POSIX_BARRIERS
+   #endif
+
+   #if defined(_POSIX_SEMAPHORES) && ((_POSIX_SEMAPHORES - 0) > 0)
+      #define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
+      #if defined(__CYGWIN__)
+         #define BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK
+      #endif
    //Some platforms have a limited (name length) named semaphore support
    #elif (defined(__FreeBSD__) && (__FreeBSD__ >= 4)) || defined(__APPLE__)
-     # define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES   
+      #define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES   
    #endif 
 
    #if ((defined _V6_ILP32_OFFBIG)  &&(_V6_ILP32_OFFBIG   - 0 > 0)) ||\
@@ -60,87 +51,83 @@
        ((defined _FILE_OFFSET_BITS) &&(_FILE_OFFSET_BITS  - 0 >= 64))||\
        ((defined _FILE_OFFSET_BITS) &&(_FILE_OFFSET_BITS  - 0 >= 64))
       #define BOOST_INTERPROCESS_UNIX_64_BIT_OR_BIGGER_OFF_T
-   #else
    #endif
 
    //Check for XSI shared memory objects. They are available in nearly all UNIX platforms
    #if !defined(__QNXNTO__)
-   # define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
+      #define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
    #endif
 
-   #if ((_POSIX_SHARED_MEMORY_OBJECTS - 0) > 0)
-   # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+   #if defined(_POSIX_SHARED_MEMORY_OBJECTS) && ((_POSIX_SHARED_MEMORY_OBJECTS - 0) > 0)
+      #define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
    #else
-   //VMS and MACOS don't define it but the have shm_open/close interface
-   # if defined(__vms)
-   #  if __CRTL_VER >= 70200000
-   #  define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
-   #  endif
-   //Mac OS has some non-conformant features like names limited to SHM_NAME_MAX
-   # elif defined (__APPLE__)
-//   #  define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
-//   #  define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS_NO_GROW
-   # endif 
+      //VMS and MACOS don't define it but they have shm_open/close interface
+      #if defined(__vms)
+         #if __CRTL_VER >= 70200000
+            #define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+         #endif
+         //Mac OS has some non-conformant features like names limited to SHM_NAME_MAX
+      #elif defined (__APPLE__)
+         //#define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+         //#define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS_NO_GROW
+      #endif
    #endif
 
    //Now check if we have only XSI shared memory
    #if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS) &&\
       !defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
-   //#  define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS_ONLY
+      //#define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS_ONLY
    #endif
 
-   #if ((_POSIX_TIMEOUTS - 0) > 0)
-   # define BOOST_INTERPROCESS_POSIX_TIMEOUTS
+   #if defined(_POSIX_TIMEOUTS) && ((_POSIX_TIMEOUTS - 0) > 0)
+      #define BOOST_INTERPROCESS_POSIX_TIMEOUTS
    #endif 
 
-
    #ifdef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
       //Some systems have filesystem-based resources, so the
       //portable "/shmname" format does not work due to permission issues
       //For those systems we need to form a path to a temporary directory:
       //          hp-ux               tru64               vms               freebsd
       #if defined(__hpux) || defined(__osf__) || defined(__vms) || (defined(__FreeBSD__) && (__FreeBSD__ < 7)) 
-      #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
+         #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
       #elif defined(__FreeBSD__)
-      #define BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
+         #define BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
       #endif
    #endif
 
    #ifdef BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
       #if defined(__osf__) || defined(__vms)
-      #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
+         #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
       #endif
    #endif
 
-   #if ((_POSIX_VERSION + 0)>= 200112L || (_XOPEN_VERSION + 0)>= 500)
-   #define BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES
+   #if defined(_POSIX_VERSION) && defined(_XOPEN_VERSION) && \
+       (((_POSIX_VERSION + 0)>= 200112L || (_XOPEN_VERSION + 0)>= 500))
+      #define BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES
    #endif
 
-#endif
+   #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
+      #define BOOST_INTERPROCESS_BSD_DERIVATIVE
+      #include <sys/sysctl.h>
+      #if defined(CTL_KERN) && defined (KERN_BOOTTIME)
+         //#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
+      #endif
+   #endif
+#endif   //!defined(BOOST_INTERPROCESS_WINDOWS)
 
-#if    !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)\
-    && !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
-#define BOOST_INTERPROCESS_PERFECT_FORWARDING
+#if    !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
+   #define BOOST_INTERPROCESS_PERFECT_FORWARDING
 #endif
 
 //Now declare some Boost.Interprocess features depending on the implementation
-
-#if defined(BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
-
-#define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
-
-#endif
-
 #if defined(BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
-
-#define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
-#define BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES
-
+   #define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
+   #define BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES
 #endif
 
 // Timeout duration use if BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING is set
 #ifndef BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS
-#define BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS 10000
+   #define BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS 10000
 #endif
 
 #include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp	(original)
+++ trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -28,7 +28,7 @@
 #include <boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp>
 #include <boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 #include <boost/detail/no_exceptions_support.hpp>
 #include <functional>       // std::less
 
Modified: trunk/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp	(original)
+++ trunk/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -26,7 +26,7 @@
 #include <boost/interprocess/smart_ptr/detail/sp_counted_base.hpp>
 #include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
 #include <boost/intrusive/pointer_traits.hpp>
 
 namespace boost {
Modified: trunk/boost/interprocess/smart_ptr/shared_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/shared_ptr.hpp	(original)
+++ trunk/boost/interprocess/smart_ptr/shared_ptr.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -137,8 +137,13 @@
       ipcdetail::sp_enable_shared_from_this<T, VoidAllocator, Deleter>( m_pn, ipcdetail::to_raw_pointer(p), ipcdetail::to_raw_pointer(p) ); 
    }
 
+   //!Copy constructs a shared_ptr. If r is empty, constructs an empty shared_ptr. Otherwise, constructs 
+   //!a shared_ptr that shares ownership with r. Never throws.
+   shared_ptr(const shared_ptr &r)
+      :  m_pn(r.m_pn) // never throws
+   {}
 
-   //!Constructs a shared_ptr that shares ownership with r and stores p.
+   //!Constructs a shared_ptr that shares ownership with other and stores p.
    //!Postconditions: get() == p && use_count() == r.use_count().
    //!Throws: nothing.
    shared_ptr(const shared_ptr &other, const pointer &p)
Added: trunk/boost/interprocess/sync/detail/condition_algorithm_8a.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/detail/condition_algorithm_8a.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,316 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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_CONDITION_ALGORITHM_8A_HPP
+#define BOOST_INTERPROCESS_DETAIL_CONDITION_ALGORITHM_8A_HPP
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+// 
+// Condition variable algorithm taken from pthreads-win32 discussion.
+//
+// The algorithm was developed by Alexander Terekhov in colaboration with
+// Louis Thomas.
+// 
+//     Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
+//
+// semBlockLock - bin.semaphore
+// semBlockQueue - semaphore
+// mtxExternal - mutex or CS
+// mtxUnblockLock - mutex or CS
+// nWaitersGone - int
+// nWaitersBlocked - int
+// nWaitersToUnblock - int
+// 
+// wait( timeout ) {
+// 
+//   [auto: register int result          ]     // error checking omitted
+//   [auto: register int nSignalsWasLeft ]
+//   [auto: register int nWaitersWasGone ]
+// 
+//   sem_wait( semBlockLock );
+//   nWaitersBlocked++;
+//   sem_post( semBlockLock );
+// 
+//   unlock( mtxExternal );
+//   bTimedOut = sem_wait( semBlockQueue,timeout );
+// 
+//   lock( mtxUnblockLock );
+//   if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
+//     if ( bTimedOut ) {                       // timeout (or canceled)
+//       if ( 0 != nWaitersBlocked ) {
+//         nWaitersBlocked--;
+//       }
+//       else {
+//         nWaitersGone++;                     // count spurious wakeups.
+//       }
+//     }
+//     if ( 0 == --nWaitersToUnblock ) {
+//       if ( 0 != nWaitersBlocked ) {
+//         sem_post( semBlockLock );           // open the gate.
+//         nSignalsWasLeft = 0;                // do not open the gate
+//                                             // below again.
+//       }
+//       else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
+//         nWaitersGone = 0;
+//       }
+//     }
+//   }
+//   else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
+//                                             // spurious semaphore :-)
+//     sem_wait( semBlockLock );
+//     nWaitersBlocked -= nWaitersGone;     // something is going on here
+//                                          //  - test of timeouts? :-)
+//     sem_post( semBlockLock );
+//     nWaitersGone = 0;
+//   }
+//   unlock( mtxUnblockLock );
+// 
+//   if ( 1 == nSignalsWasLeft ) {
+//     if ( 0 != nWaitersWasGone ) {
+//       // sem_adjust( semBlockQueue,-nWaitersWasGone );
+//       while ( nWaitersWasGone-- ) {
+//         sem_wait( semBlockQueue );       // better now than spurious later
+//       }
+//     } sem_post( semBlockLock );          // open the gate
+//   }
+// 
+//   lock( mtxExternal );
+// 
+//   return ( bTimedOut ) ? ETIMEOUT : 0;
+// }
+// 
+// signal(bAll) {
+// 
+//   [auto: register int result         ]
+//   [auto: register int nSignalsToIssue]
+// 
+//   lock( mtxUnblockLock );
+// 
+//   if ( 0 != nWaitersToUnblock ) {        // the gate is closed!!!
+//     if ( 0 == nWaitersBlocked ) {        // NO-OP
+//       return unlock( mtxUnblockLock );
+//     }
+//     if (bAll) {
+//       nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
+//       nWaitersBlocked = 0;
+//     }
+//     else {
+//       nSignalsToIssue = 1;
+//       nWaitersToUnblock++;
+//       nWaitersBlocked--;
+//     }
+//   }
+//   else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+//     sem_wait( semBlockLock );                  // close the gate
+//     if ( 0 != nWaitersGone ) {
+//       nWaitersBlocked -= nWaitersGone;
+//       nWaitersGone = 0;
+//     }
+//     if (bAll) {
+//       nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
+//       nWaitersBlocked = 0;
+//     }
+//     else {
+//       nSignalsToIssue = nWaitersToUnblock = 1;
+//       nWaitersBlocked--;
+//     }
+//   }
+//   else { // NO-OP
+//     return unlock( mtxUnblockLock );
+//   }
+// 
+//   unlock( mtxUnblockLock );
+//   sem_post( semBlockQueue,nSignalsToIssue );
+//   return result;
+// }
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+
+// Required interface for ConditionMembers
+// class ConditionMembers
+// {
+//    typedef implementation_defined semaphore_type;
+//    typedef implementation_defined mutex_type;
+//    typedef implementation_defined integer_type;
+//
+//    integer_type    &get_nwaiters_blocked()
+//    integer_type    &get_nwaiters_gone()
+//    integer_type    &get_nwaiters_to_unblock()
+//    semaphore_type  &get_sem_block_queue()
+//    semaphore_type  &get_sem_block_lock()
+//    mutex_type      &get_mtx_unblock_lock()
+// };
+// 
+template<class ConditionMembers>
+class condition_algorithm_8a
+{
+   private:
+   condition_algorithm_8a();
+   ~condition_algorithm_8a();
+   condition_algorithm_8a(const condition_algorithm_8a &);
+   condition_algorithm_8a &operator=(const condition_algorithm_8a &);
+
+   typedef typename ConditionMembers::semaphore_type  semaphore_type;
+   typedef typename ConditionMembers::mutex_type      mutex_type;
+   typedef typename ConditionMembers::integer_type    integer_type;
+
+   // nwaiters_blocked == 0
+   // nwaiters_gone() == 0
+   // nwaiters_to_unblock == 0
+   // sem_block_queue() == initial count 0
+   // sem_block_lock() == initial count 1
+   // mtx_unblock_lock (unlocked)
+
+   public:
+   template<class InterprocessMutex>
+   static bool wait  (ConditionMembers &data, bool timeout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mut);
+   static void signal(ConditionMembers &data, bool broadcast);
+};
+
+template<class ConditionMembers>
+inline void condition_algorithm_8a<ConditionMembers>::signal(ConditionMembers &data, bool broadcast)
+{
+   integer_type nsignals_to_issue;
+
+   {
+      scoped_lock<mutex_type> locker(data.get_mtx_unblock_lock());
+
+      if ( 0 != data.get_nwaiters_to_unblock() ) {        // the gate is closed!!!
+         if ( 0 == data.get_nwaiters_blocked() ) {        // NO-OP
+            //locker's destructor triggers data.get_mtx_unblock_lock().unlock() 
+            return;
+         }
+         if (broadcast) {
+            data.get_nwaiters_to_unblock() += nsignals_to_issue = data.get_nwaiters_blocked();
+            data.get_nwaiters_blocked() = 0;
+         }
+         else {
+            nsignals_to_issue = 1;
+            data.get_nwaiters_to_unblock()++;
+            data.get_nwaiters_blocked()--;
+         }
+      }
+      else if ( data.get_nwaiters_blocked() > data.get_nwaiters_gone() ) { // HARMLESS RACE CONDITION!
+         data.get_sem_block_lock().wait();                      // close the gate
+         if ( 0 != data.get_nwaiters_gone() ) {
+            data.get_nwaiters_blocked() -= data.get_nwaiters_gone();
+            data.get_nwaiters_gone() = 0;
+         }
+         if (broadcast) {
+            nsignals_to_issue = data.get_nwaiters_to_unblock() = data.get_nwaiters_blocked();
+            data.get_nwaiters_blocked() = 0;
+         }
+         else {
+            nsignals_to_issue = data.get_nwaiters_to_unblock() = 1;
+            data.get_nwaiters_blocked()--;
+         }
+      }
+      else { // NO-OP
+         //locker's destructor triggers data.get_mtx_unblock_lock().unlock() 
+         return;
+      }
+      //locker's destructor triggers data.get_mtx_unblock_lock().unlock() 
+   }
+   data.get_sem_block_queue().post(nsignals_to_issue);
+}
+
+template<class ConditionMembers>
+template<class InterprocessMutex>
+inline bool condition_algorithm_8a<ConditionMembers>::wait
+   (ConditionMembers &data, bool tout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mtxExternal)
+{
+   //Initialize to avoid warnings
+   integer_type nsignals_was_left = 0;
+   integer_type nwaiters_was_gone = 0;
+ 
+   data.get_sem_block_lock().wait();
+   ++data.get_nwaiters_blocked();
+   data.get_sem_block_lock().post();
+
+   struct scoped_unlock
+   {
+      InterprocessMutex & mut;
+      scoped_unlock(InterprocessMutex & m)
+         : mut(m)
+      {  m.unlock();  }
+
+      ~scoped_unlock()
+      {  mut.lock();  }
+   } unlocker(mtxExternal);
+ 
+
+   bool bTimedOut = tout_enabled ? !data.get_sem_block_queue().timed_wait(abs_time) : (data.get_sem_block_queue().wait(), false);
+ 
+   {
+      scoped_lock<mutex_type> locker(data.get_mtx_unblock_lock());
+      if ( 0 != (nsignals_was_left = data.get_nwaiters_to_unblock()) ) {
+         if ( bTimedOut ) {                       // timeout (or canceled)
+            if ( 0 != data.get_nwaiters_blocked() ) {
+               data.get_nwaiters_blocked()--;
+            }
+            else {
+               data.get_nwaiters_gone()++;                     // count spurious wakeups.
+            }
+         }
+         if ( 0 == --data.get_nwaiters_to_unblock() ) {
+            if ( 0 != data.get_nwaiters_blocked() ) {
+               data.get_sem_block_lock().post();          // open the gate.
+               nsignals_was_left = 0;          // do not open the gate below again.
+            }
+            else if ( 0 != (nwaiters_was_gone = data.get_nwaiters_gone()) ) {
+               data.get_nwaiters_gone() = 0;
+            }
+         }
+      }
+      else if ( (std::numeric_limits<integer_type>::max)()/2
+                == ++data.get_nwaiters_gone() ) { // timeout/canceled or spurious semaphore :-)
+         data.get_sem_block_lock().wait();
+         data.get_nwaiters_blocked() -= data.get_nwaiters_gone();       // something is going on here - test of timeouts? :-)
+         data.get_sem_block_lock().post();
+         data.get_nwaiters_gone() = 0;
+      }
+      //locker's destructor triggers data.get_mtx_unblock_lock().unlock() 
+   }  
+ 
+   if ( 1 == nsignals_was_left ) {
+      if ( 0 != nwaiters_was_gone ) {
+         // sem_adjust( data.get_sem_block_queue(),-nwaiters_was_gone );
+         while ( nwaiters_was_gone-- ) {
+            data.get_sem_block_queue().wait();       // better now than spurious later
+         }
+      }
+      data.get_sem_block_lock().post(); // open the gate
+   }
+ 
+   //mtxExternal.lock(); called from unlocker
+ 
+   return ( bTimedOut ) ? false : true;
+}
+
+}  //namespace ipcdetail
+}  //namespace interprocess
+}  //namespace boost
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif   //BOOST_INTERPROCESS_DETAIL_CONDITION_ALGORITHM_8A_HPP
Modified: trunk/boost/interprocess/sync/interprocess_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_condition.hpp	(original)
+++ trunk/boost/interprocess/sync/interprocess_condition.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -30,9 +30,9 @@
    #include <boost/interprocess/sync/posix/condition.hpp>
    #define BOOST_INTERPROCESS_USE_POSIX
 //Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-//   #include <boost/interprocess/sync/windows/condition.hpp>
-//   #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+   #include <boost/interprocess/sync/windows/condition.hpp>
+   #define BOOST_INTERPROCESS_USE_WINDOWS
 #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    #include <boost/interprocess/sync/spin/condition.hpp>
    #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
Modified: trunk/boost/interprocess/sync/interprocess_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_mutex.hpp	(original)
+++ trunk/boost/interprocess/sync/interprocess_mutex.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -31,9 +31,9 @@
    #include <boost/interprocess/sync/posix/mutex.hpp>
    #define BOOST_INTERPROCESS_USE_POSIX
 //Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-//   #include <boost/interprocess/sync/windows/mutex.hpp>
-//   #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+   #include <boost/interprocess/sync/windows/mutex.hpp>
+   #define BOOST_INTERPROCESS_USE_WINDOWS
 #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    #include <boost/interprocess/sync/spin/mutex.hpp>
    #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
Modified: trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp	(original)
+++ trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -43,9 +43,9 @@
    #include <boost/interprocess/sync/posix/recursive_mutex.hpp>
    #define BOOST_INTERPROCESS_USE_POSIX
 //Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-//   #include <boost/interprocess/sync/windows/recursive_mutex.hpp>
-//   #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+   #include <boost/interprocess/sync/windows/recursive_mutex.hpp>
+   #define BOOST_INTERPROCESS_USE_WINDOWS
 #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    #include <boost/interprocess/sync/spin/recursive_mutex.hpp>
    #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
Modified: trunk/boost/interprocess/sync/interprocess_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_semaphore.hpp	(original)
+++ trunk/boost/interprocess/sync/interprocess_semaphore.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -29,9 +29,9 @@
    #include <boost/interprocess/sync/posix/semaphore.hpp>
    #define BOOST_INTERPROCESS_USE_POSIX
 //Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-//   #include <boost/interprocess/sync/windows/semaphore.hpp>
-//   #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+   #include <boost/interprocess/sync/windows/semaphore.hpp>
+   #define BOOST_INTERPROCESS_USE_WINDOWS
 #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    #include <boost/interprocess/sync/spin/semaphore.hpp>
    #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
Modified: trunk/boost/interprocess/sync/named_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_condition.hpp	(original)
+++ trunk/boost/interprocess/sync/named_condition.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -22,7 +22,12 @@
 #include <boost/interprocess/detail/interprocess_tester.hpp>
 #include <boost/interprocess/permissions.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-#include <boost/interprocess/sync/shm/named_condition.hpp>
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+   #include <boost/interprocess/sync/windows/named_condition.hpp>
+   #define BOOST_INTERPROCESS_USE_WINDOWS
+#else
+   #include <boost/interprocess/sync/shm/named_condition.hpp>
+#endif
 
 //!\file
 //!Describes a named condition class for inter-process synchronization
@@ -110,7 +115,12 @@
 
    /// @cond
    private:
-   ipcdetail::shm_named_condition m_cond;
+   #if defined(BOOST_INTERPROCESS_USE_WINDOWS)
+   typedef ipcdetail::windows_named_condition   condition_type;
+   #else
+   typedef ipcdetail::shm_named_condition       condition_type;
+   #endif
+   condition_type m_cond;
 
    friend class ipcdetail::interprocess_tester;
    void dont_close_on_destruction()
@@ -160,7 +170,7 @@
 {  return m_cond.timed_wait(lock, abs_time, pred);  }
 
 inline bool named_condition::remove(const char *name)
-{  return ipcdetail::shm_named_condition::remove(name); }
+{  return condition_type::remove(name); }
 
 /// @endcond
 
Modified: trunk/boost/interprocess/sync/named_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_mutex.hpp	(original)
+++ trunk/boost/interprocess/sync/named_mutex.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -24,7 +24,11 @@
 #include <boost/interprocess/permissions.hpp>
 
 #if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
-#include <boost/interprocess/sync/posix/named_mutex.hpp>
+   #include <boost/interprocess/sync/posix/named_mutex.hpp>
+   #define BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+   #include <boost/interprocess/sync/windows/named_mutex.hpp>
+   #define BOOST_INTERPROCESS_USE_WINDOWS
 #else
 #include <boost/interprocess/sync/shm/named_mutex.hpp>
 #endif
@@ -104,15 +108,20 @@
    friend class ipcdetail::interprocess_tester;
    void dont_close_on_destruction();
 
-   #if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
-   typedef ipcdetail::posix_named_mutex   impl_t;
-   impl_t m_mut;
+   #if defined(BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES)
+      typedef ipcdetail::posix_named_mutex   impl_t;
+      impl_t m_mut;
+      #undef BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES
+   #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
+      typedef ipcdetail::windows_named_mutex   impl_t;
+      impl_t m_mut;
+      #undef BOOST_INTERPROCESS_USE_WINDOWS
    #else
-   typedef ipcdetail::shm_named_mutex     impl_t;
-   impl_t m_mut;
-   public:
-   interprocess_mutex *mutex() const
-   {  return m_mut.mutex(); }
+      typedef ipcdetail::shm_named_mutex     impl_t;
+      impl_t m_mut;
+      public:
+      interprocess_mutex *mutex() const
+      {  return m_mut.mutex(); }
    #endif
 
    /// @endcond
Modified: trunk/boost/interprocess/sync/named_recursive_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_recursive_mutex.hpp	(original)
+++ trunk/boost/interprocess/sync/named_recursive_mutex.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -20,7 +20,12 @@
 #include <boost/interprocess/creation_tags.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 #include <boost/interprocess/permissions.hpp>
-#include <boost/interprocess/sync/shm/named_recursive_mutex.hpp>
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+   #include <boost/interprocess/sync/windows/named_recursive_mutex.hpp>
+   #define BOOST_INTERPROCESS_USE_WINDOWS
+#else
+   #include <boost/interprocess/sync/shm/named_recursive_mutex.hpp>
+#endif
 
 //!\file
 //!Describes a named named_recursive_mutex class for inter-process synchronization
@@ -97,7 +102,12 @@
    friend class ipcdetail::interprocess_tester;
    void dont_close_on_destruction();
 
-   typedef ipcdetail::shm_named_recursive_mutex impl_t;
+   #if defined(BOOST_INTERPROCESS_USE_WINDOWS)
+      typedef ipcdetail::windows_named_recursive_mutex   impl_t;
+      #undef BOOST_INTERPROCESS_USE_WINDOWS
+   #else
+      typedef ipcdetail::shm_named_recursive_mutex impl_t;
+   #endif
    impl_t m_mut;
 
    /// @endcond
Modified: trunk/boost/interprocess/sync/named_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_semaphore.hpp	(original)
+++ trunk/boost/interprocess/sync/named_semaphore.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -25,6 +25,10 @@
 
 #if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES)
 #include <boost/interprocess/sync/posix/named_semaphore.hpp>
+//Experimental...
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+   #include <boost/interprocess/sync/windows/named_semaphore.hpp>
+   #define BOOST_INTERPROCESS_USE_WINDOWS
 #else
 #include <boost/interprocess/sync/shm/named_semaphore.hpp>
 #endif
@@ -106,9 +110,12 @@
    void dont_close_on_destruction();
 
    #if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES)
-      typedef ipcdetail::posix_named_semaphore  impl_t;
+      typedef ipcdetail::posix_named_semaphore   impl_t;
+   #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
+      #undef BOOST_INTERPROCESS_USE_WINDOWS
+      typedef ipcdetail::windows_named_semaphore impl_t;
    #else
-      typedef ipcdetail::shm_named_semaphore    impl_t;
+      typedef ipcdetail::shm_named_semaphore     impl_t;
    #endif
    impl_t m_sem;
    /// @endcond
Modified: trunk/boost/interprocess/sync/shm/named_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/shm/named_condition.hpp	(original)
+++ trunk/boost/interprocess/sync/shm/named_condition.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -28,7 +28,7 @@
 #include <boost/interprocess/sync/shm/named_creation_functor.hpp>
 #include <boost/interprocess/sync/named_mutex.hpp>
 #include <boost/interprocess/permissions.hpp>
-#if defined BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
+#if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
 #include <boost/interprocess/sync/interprocess_mutex.hpp>
 #include <boost/interprocess/sync/scoped_lock.hpp>
 #endif
@@ -42,7 +42,7 @@
 namespace ipcdetail {
 
 /// @cond
-namespace ipcdetail{ class interprocess_tester; }
+class interprocess_tester;
 /// @endcond
 
 //! A global condition variable that can be created by name.
@@ -147,6 +147,9 @@
       void unlock()  {   l_.lock();     }
    };
 
+   //If named mutex uses POSIX semaphores, then the shm based condition variable
+   //must use it's internal lock to wait, as sem_t does not store a pthread_mutex_t
+   //instance needed by pthread_mutex_cond_t
    #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
       interprocess_mutex *mutex() const
       {  return &static_cast<condition_holder*>(m_shmem.get_user_address())->mutex_; }
@@ -184,7 +187,7 @@
          internal_lock.swap(internal_unlock);  
          return this->condition()->timed_wait(internal_unlock, abs_time);  
       }
-   #else
+   #else //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
       template<class Lock>
       class lock_wrapper
       {
@@ -210,7 +213,7 @@
          private:
          Lock &l_;
       };
-   #endif
+   #endif   //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
 
    friend class boost::interprocess::ipcdetail::interprocess_tester;
    void dont_close_on_destruction();
Modified: trunk/boost/interprocess/sync/windows/condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/windows/condition.hpp	(original)
+++ trunk/boost/interprocess/sync/windows/condition.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -20,133 +20,8 @@
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/sync/windows/semaphore.hpp>
 #include <boost/interprocess/sync/windows/mutex.hpp>
-#include <boost/cstdint.hpp>
-#include <limits>
+#include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
 
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-// 
-// Condition variable algorithm taken from pthreads-win32 discussion.
-//
-// The algorithm was developed by Alexander Terekhov in colaboration with
-// Louis Thomas.
-// 
-//     Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
-//
-// semBlockLock - bin.semaphore
-// semBlockQueue - semaphore
-// mtxExternal - mutex or CS
-// mtxUnblockLock - mutex or CS
-// nWaitersGone - int
-// nWaitersBlocked - int
-// nWaitersToUnblock - int
-// 
-// wait( timeout ) {
-// 
-//   [auto: register int result          ]     // error checking omitted
-//   [auto: register int nSignalsWasLeft ]
-//   [auto: register int nWaitersWasGone ]
-// 
-//   sem_wait( semBlockLock );
-//   nWaitersBlocked++;
-//   sem_post( semBlockLock );
-// 
-//   unlock( mtxExternal );
-//   bTimedOut = sem_wait( semBlockQueue,timeout );
-// 
-//   lock( mtxUnblockLock );
-//   if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
-//     if ( bTimedOut ) {                       // timeout (or canceled)
-//       if ( 0 != nWaitersBlocked ) {
-//         nWaitersBlocked--;
-//       }
-//       else {
-//         nWaitersGone++;                     // count spurious wakeups.
-//       }
-//     }
-//     if ( 0 == --nWaitersToUnblock ) {
-//       if ( 0 != nWaitersBlocked ) {
-//         sem_post( semBlockLock );           // open the gate.
-//         nSignalsWasLeft = 0;                // do not open the gate
-//                                             // below again.
-//       }
-//       else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
-//         nWaitersGone = 0;
-//       }
-//     }
-//   }
-//   else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
-//                                             // spurious semaphore :-)
-//     sem_wait( semBlockLock );
-//     nWaitersBlocked -= nWaitersGone;     // something is going on here
-//                                          //  - test of timeouts? :-)
-//     sem_post( semBlockLock );
-//     nWaitersGone = 0;
-//   }
-//   unlock( mtxUnblockLock );
-// 
-//   if ( 1 == nSignalsWasLeft ) {
-//     if ( 0 != nWaitersWasGone ) {
-//       // sem_adjust( semBlockQueue,-nWaitersWasGone );
-//       while ( nWaitersWasGone-- ) {
-//         sem_wait( semBlockQueue );       // better now than spurious later
-//       }
-//     } sem_post( semBlockLock );          // open the gate
-//   }
-// 
-//   lock( mtxExternal );
-// 
-//   return ( bTimedOut ) ? ETIMEOUT : 0;
-// }
-// 
-// signal(bAll) {
-// 
-//   [auto: register int result         ]
-//   [auto: register int nSignalsToIssue]
-// 
-//   lock( mtxUnblockLock );
-// 
-//   if ( 0 != nWaitersToUnblock ) {        // the gate is closed!!!
-//     if ( 0 == nWaitersBlocked ) {        // NO-OP
-//       return unlock( mtxUnblockLock );
-//     }
-//     if (bAll) {
-//       nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
-//       nWaitersBlocked = 0;
-//     }
-//     else {
-//       nSignalsToIssue = 1;
-//       nWaitersToUnblock++;
-//       nWaitersBlocked--;
-//     }
-//   }
-//   else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
-//     sem_wait( semBlockLock );                  // close the gate
-//     if ( 0 != nWaitersGone ) {
-//       nWaitersBlocked -= nWaitersGone;
-//       nWaitersGone = 0;
-//     }
-//     if (bAll) {
-//       nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
-//       nWaitersBlocked = 0;
-//     }
-//     else {
-//       nSignalsToIssue = nWaitersToUnblock = 1;
-//       nWaitersBlocked--;
-//     }
-//   }
-//   else { // NO-OP
-//     return unlock( mtxUnblockLock );
-//   }
-// 
-//   unlock( mtxUnblockLock );
-//   sem_post( semBlockQueue,nSignalsToIssue );
-//   return result;
-// }
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
 
 namespace boost {
 namespace interprocess {
@@ -156,6 +31,7 @@
 {
    windows_condition(const windows_condition &);
    windows_condition &operator=(const windows_condition &);
+
    public:
    windows_condition();
    ~windows_condition();
@@ -217,162 +93,71 @@
 
    private:
 
-   template<class InterprocessMutex>
-   bool do_timed_wait(bool timeout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mut);
-   void do_signal    (bool broadcast);
+   struct condition_data
+   {
+      typedef boost::int32_t     integer_type;
+      typedef windows_semaphore  semaphore_type;
+      typedef windows_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;  }
+
+      boost::int32_t    m_nwaiters_blocked;
+      boost::int32_t    m_nwaiters_gone;
+      boost::int32_t    m_nwaiters_to_unblock;
+      windows_semaphore m_sem_block_queue;
+      windows_semaphore m_sem_block_lock;
+      windows_mutex     m_mtx_unblock_lock;
+   } m_condition_data;
 
-   boost::int32_t    m_nwaiters_blocked;
-   boost::int32_t    m_nwaiters_gone;
-   boost::int32_t    m_nwaiters_to_unblock;
-   windows_semaphore m_sem_block_queue;
-   windows_semaphore m_sem_block_lock;
-   windows_mutex     m_mtx_unblock_lock;
+   typedef condition_algorithm_8a<condition_data> algorithm_type;
 };
 
 inline windows_condition::windows_condition()
- : 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()
+   : m_condition_data()
 {}
 
 inline windows_condition::~windows_condition()
 {}
 
 inline void windows_condition::notify_one()
-{  this->do_signal(false);  }
+{  algorithm_type::signal(m_condition_data, false);  }
 
 inline void windows_condition::notify_all()
-{  this->do_signal(true);  }
-
-inline void windows_condition::do_signal(bool broadcast)
-{
-   boost::int32_t nsignals_to_issue;
-
-   {
-      scoped_lock<windows_mutex> locker(m_mtx_unblock_lock);
-
-      if ( 0 != m_nwaiters_to_unblock ) {        // the gate is closed!!!
-         if ( 0 == m_nwaiters_blocked ) {        // NO-OP
-            //locker's destructor triggers m_mtx_unblock_lock.unlock() 
-            return;
-         }
-         if (broadcast) {
-            m_nwaiters_to_unblock += nsignals_to_issue = m_nwaiters_blocked;
-            m_nwaiters_blocked = 0;
-         }
-         else {
-            nsignals_to_issue = 1;
-            m_nwaiters_to_unblock++;
-            m_nwaiters_blocked--;
-         }
-      }
-      else if ( m_nwaiters_blocked > m_nwaiters_gone ) { // HARMLESS RACE CONDITION!
-         m_sem_block_lock.wait();                      // close the gate
-         if ( 0 != m_nwaiters_gone ) {
-            m_nwaiters_blocked -= m_nwaiters_gone;
-            m_nwaiters_gone = 0;
-         }
-         if (broadcast) {
-            nsignals_to_issue = m_nwaiters_to_unblock = m_nwaiters_blocked;
-            m_nwaiters_blocked = 0;
-         }
-         else {
-            nsignals_to_issue = m_nwaiters_to_unblock = 1;
-            m_nwaiters_blocked--;
-         }
-      }
-      else { // NO-OP
-         //locker's destructor triggers m_mtx_unblock_lock.unlock() 
-         return;
-      }
-      //locker's destructor triggers m_mtx_unblock_lock.unlock() 
-   }
-   m_sem_block_queue.post(nsignals_to_issue);
-}
+{  algorithm_type::signal(m_condition_data, true);  }
 
 template<class InterprocessMutex>
 inline void windows_condition::do_wait(InterprocessMutex &mut)
-{  this->do_timed_wait(false, boost::posix_time::ptime(), mut);  }
+{  algorithm_type::wait(m_condition_data, false, boost::posix_time::ptime(), mut);  }
 
 template<class InterprocessMutex>
 inline bool windows_condition::do_timed_wait
    (const boost::posix_time::ptime &abs_time, InterprocessMutex &mut)
-{  return this->do_timed_wait(true, abs_time, mut);  }
-
-template<class InterprocessMutex>
-inline bool windows_condition::do_timed_wait
-   (bool tout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mtxExternal)
-{
-   //Initialize to avoid warnings
-   boost::int32_t nsignals_was_left = 0;
-   boost::int32_t nwaiters_was_gone = 0;
- 
-   m_sem_block_lock.wait();
-   ++m_nwaiters_blocked;
-   m_sem_block_lock.post();
-
-   struct scoped_unlock
-   {
-      InterprocessMutex & mut;
-      scoped_unlock(InterprocessMutex & m)
-         : mut(m)
-      {  m.unlock();  }
-
-      ~scoped_unlock()
-      {  mut.lock();  }
-   } unlocker(mtxExternal);
- 
-
-   bool bTimedOut = tout_enabled ? !m_sem_block_queue.timed_wait(abs_time) : (m_sem_block_queue.wait(), false);
- 
-   {
-      scoped_lock<windows_mutex> locker(m_mtx_unblock_lock);
-      if ( 0 != (nsignals_was_left = m_nwaiters_to_unblock) ) {
-         if ( bTimedOut ) {                       // timeout (or canceled)
-            if ( 0 != m_nwaiters_blocked ) {
-               m_nwaiters_blocked--;
-            }
-            else {
-               m_nwaiters_gone++;                     // count spurious wakeups.
-            }
-         }
-         if ( 0 == --m_nwaiters_to_unblock ) {
-            if ( 0 != m_nwaiters_blocked ) {
-               m_sem_block_lock.post();          // open the gate.
-               nsignals_was_left = 0;          // do not open the gate below again.
-            }
-            else if ( 0 != (nwaiters_was_gone = m_nwaiters_gone) ) {
-               m_nwaiters_gone = 0;
-            }
-         }
-      }
-      else if ( (std::numeric_limits<boost::int32_t>::max)()/2
-                == ++m_nwaiters_gone ) { // timeout/canceled or spurious semaphore :-)
-         m_sem_block_lock.wait();
-         m_nwaiters_blocked -= m_nwaiters_gone;       // something is going on here - test of timeouts? :-)
-         m_sem_block_lock.post();
-         m_nwaiters_gone = 0;
-      }
-      //locker's destructor triggers m_mtx_unblock_lock.unlock() 
-   }  
- 
-   if ( 1 == nsignals_was_left ) {
-      if ( 0 != nwaiters_was_gone ) {
-         // sem_adjust( m_sem_block_queue,-nwaiters_was_gone );
-         while ( nwaiters_was_gone-- ) {
-            m_sem_block_queue.wait();       // better now than spurious later
-         }
-      }
-      m_sem_block_lock.post(); // open the gate
-   }
- 
-   //mtxExternal.lock(); called from unlocker
- 
-   return ( bTimedOut ) ? false : true;
-}
+{  return algorithm_type::wait(m_condition_data, true, abs_time, mut);  }
 
 }  //namespace ipcdetail
 }  //namespace interprocess
Modified: trunk/boost/interprocess/sync/windows/mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/windows/mutex.hpp	(original)
+++ trunk/boost/interprocess/sync/windows/mutex.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -19,8 +19,9 @@
 #include <boost/interprocess/detail/workaround.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 #include <boost/interprocess/detail/win32_api.hpp>
-#include <boost/interprocess/detail/intermodule_singleton.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>
 
 
@@ -51,7 +52,7 @@
    : id_()
 {
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
+      windows_intermodule_singleton<sync_handles>::get();
    //Create mutex with the initial count
    bool open_or_created;
    handles.obtain_mutex(this->id_, &open_or_created);
@@ -64,68 +65,44 @@
 inline windows_mutex::~windows_mutex() 
 {
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
+      windows_intermodule_singleton<sync_handles>::get();
    handles.destroy_handle(this->id_);
 }
 
 inline void windows_mutex::lock(void)
 {
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
+      windows_intermodule_singleton<sync_handles>::get();
    //This can throw
-   void *hnd = handles.obtain_mutex(this->id_);
-   unsigned long ret = winapi::wait_for_single_object(hnd, winapi::infinite_time);
-   if(ret == winapi::wait_failed){
-      error_info err(winapi::get_last_error());
-      throw interprocess_exception(err);
-   }
+   winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+   mut.lock();
 }
 
 inline bool windows_mutex::try_lock(void)
 {
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
+      windows_intermodule_singleton<sync_handles>::get();
    //This can throw
-   void *hnd = handles.obtain_mutex(this->id_);
-   unsigned long ret = winapi::wait_for_single_object(hnd, 0);
-   if(ret == winapi::wait_failed){
-      error_info err(winapi::get_last_error());
-      throw interprocess_exception(err);
-   }
-   return ret != winapi::wait_timeout;
+   winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+   return mut.try_lock();
 }
 
 inline bool windows_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
 {
-   if(abs_time == boost::posix_time::pos_infin){
-      this->lock();
-      return true;
-   }
-   boost::posix_time::ptime now
-      = boost::posix_time::microsec_clock::universal_time();
-
-   unsigned long ms = (unsigned long)(abs_time-now).total_milliseconds();
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
+      windows_intermodule_singleton<sync_handles>::get();
    //This can throw
-   void *hnd = handles.obtain_mutex(this->id_);
-   unsigned long ret = winapi::wait_for_single_object(hnd, ms);
-   if(ret == winapi::wait_failed){
-      error_info err(winapi::get_last_error());
-      throw interprocess_exception(err);
-   }
-   return ret != winapi::wait_timeout;
+   winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+   return mut.timed_lock(abs_time);
 }
 
 inline void windows_mutex::unlock(void)
 {
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
+      windows_intermodule_singleton<sync_handles>::get();
    //This can throw
-   void *hnd = handles.obtain_mutex(this->id_);
-   int ret = winapi::release_mutex(hnd);
-   (void)ret;
-   assert(ret);
+   winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+   return mut.unlock();
 }
 
 }  //namespace ipcdetail {
Added: trunk/boost/interprocess/sync/windows/named_condition.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/windows/named_condition.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,331 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  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/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/windows/named_sync.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
+#include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+class windows_named_condition
+{
+   /// @cond
+
+   //Non-copyable
+   windows_named_condition();
+   windows_named_condition(const windows_named_condition &);
+   windows_named_condition &operator=(const windows_named_condition &);
+   /// @endcond
+
+   public:
+   windows_named_condition(create_only_t, const char *name, const permissions &perm = permissions());
+
+   windows_named_condition(open_or_create_t, const char *name, const permissions &perm = permissions());
+
+   windows_named_condition(open_only_t, const char *name);
+
+   ~windows_named_condition();
+
+   //!If there is a thread waiting on *this, change that 
+   //!thread's state to ready. Otherwise there is no effect.*/
+   void notify_one();
+
+   //!Change the state of all threads waiting on *this to ready.
+   //!If there are no waiting threads, notify_all() has no effect.
+   void notify_all();
+
+   //!Releases the lock on the named_mutex object associated with lock, blocks 
+   //!the current thread of execution until readied by a call to 
+   //!this->notify_one() or this->notify_all(), and then reacquires the lock.
+   template <typename L>
+   void wait(L& lock);
+
+   //!The same as:
+   //!while (!pred()) wait(lock)
+   template <typename L, typename Pr>
+   void wait(L& lock, Pr pred);
+
+   //!Releases the lock on the named_mutex object associated with lock, blocks 
+   //!the current thread of execution until readied by a call to 
+   //!this->notify_one() or this->notify_all(), or until time abs_time is reached, 
+   //!and then reacquires the lock.
+   //!Returns: false if time abs_time is reached, otherwise true.
+   template <typename L>
+   bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time);
+
+   //!The same as:   while (!pred()) { 
+   //!                  if (!timed_wait(lock, abs_time)) return pred(); 
+   //!               } return true;
+   template <typename L, typename Pr>
+   bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred);
+
+   static bool remove(const char *name);
+
+   /// @cond
+   private:
+   friend class interprocess_tester;
+   void dont_close_on_destruction();
+
+   template <class InterprocessMutex>
+   void do_wait(InterprocessMutex& lock);
+
+   template <class InterprocessMutex>
+   bool do_timed_wait(const boost::posix_time::ptime &abs_time, InterprocessMutex& lock);
+
+   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;
+   } m_condition_data;
+
+   typedef condition_algorithm_8a<condition_data> algorithm_type;
+
+   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
+      {  return sizeof(sem_counts);   }
+
+      virtual const void *buffer_with_final_data_to_file()
+      {
+         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()
+      {
+         sem_counts[0] = 0;
+         sem_counts[1] = 1;
+         return &sem_counts;
+      }
+
+      virtual void *buffer_to_store_init_data_from_file()
+      {  return &sem_counts; }
+
+      virtual bool open(create_enum_t, const char *id_name)
+      {
+         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::string aux_str  = "Global\\bipc.cond.";
+         aux_str += id_name;
+         std::size_t pos = aux_str.size();
+
+         //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))
+            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))
+            return false;
+         aux_str.erase(pos);
+
+         //mtx_unblock_lock
+         aux_str += "_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;
+      }
+
+      virtual void close()
+      {
+         m_condition_data.m_sem_block_queue.close();
+         m_condition_data.m_sem_block_lock.close();
+         m_condition_data.m_mtx_unblock_lock.close();
+         m_condition_data.m_nwaiters_blocked = 0;
+         m_condition_data.m_nwaiters_gone = 0;
+         m_condition_data.m_nwaiters_to_unblock = 0;
+      }
+
+      virtual ~named_cond_callbacks()
+      {}
+
+      private:
+      condition_data &m_condition_data;
+   };
+
+   windows_named_sync   m_named_sync;
+   /// @endcond
+};
+
+inline windows_named_condition::~windows_named_condition()
+{
+   named_cond_callbacks callbacks(m_condition_data);
+   m_named_sync.close(callbacks);
+}
+
+inline void windows_named_condition::dont_close_on_destruction()
+{}
+
+inline windows_named_condition::windows_named_condition
+   (create_only_t, const char *name, const permissions &perm)
+   : m_condition_data()
+{
+   named_cond_callbacks callbacks(m_condition_data);
+   m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
+}
+
+inline windows_named_condition::windows_named_condition
+   (open_or_create_t, const char *name, const permissions &perm)
+   : m_condition_data()
+{
+   named_cond_callbacks callbacks(m_condition_data);
+   m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
+}
+
+inline windows_named_condition::windows_named_condition(open_only_t, const char *name)
+   : m_condition_data()
+{
+   named_cond_callbacks callbacks(m_condition_data);
+   m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
+}
+
+inline void windows_named_condition::notify_one()
+{  algorithm_type::signal(m_condition_data, false);  }
+
+inline void windows_named_condition::notify_all()
+{  algorithm_type::signal(m_condition_data, true);  }
+
+template<class InterprocessMutex>
+inline void windows_named_condition::do_wait(InterprocessMutex &mut)
+{  algorithm_type::wait(m_condition_data, false, boost::posix_time::ptime(), mut);  }
+
+template<class InterprocessMutex>
+inline bool windows_named_condition::do_timed_wait
+   (const boost::posix_time::ptime &abs_time, InterprocessMutex &mut)
+{  return algorithm_type::wait(m_condition_data, true, abs_time, mut);  }
+
+template <typename L>
+inline void windows_named_condition::wait(L& lock)
+{
+   if (!lock)
+      throw lock_exception();
+   this->do_wait(*lock.mutex());
+}
+
+template <typename L, typename Pr>
+inline void windows_named_condition::wait(L& lock, Pr pred)
+{
+   if (!lock)
+      throw lock_exception();
+   while (!pred())
+      this->do_wait(*lock.mutex());
+}
+
+template <typename L>
+inline bool windows_named_condition::timed_wait
+   (L& lock, const boost::posix_time::ptime &abs_time)
+{
+   if(abs_time == boost::posix_time::pos_infin){
+      this->wait(lock);
+      return true;
+   }
+   if (!lock)
+      throw lock_exception();
+   return this->do_timed_wait(abs_time, *lock.mutex());
+}
+
+template <typename L, typename Pr>
+inline bool windows_named_condition::timed_wait
+   (L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+{
+   if(abs_time == boost::posix_time::pos_infin){
+      this->wait(lock, pred);
+      return true;
+   }
+   if (!lock)
+      throw lock_exception();
+
+   while (!pred()){
+      if(!this->do_timed_wait(abs_time, *lock.mutex())){
+         return pred();
+      }
+   }
+   return true;
+}
+
+inline bool windows_named_condition::remove(const char *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_CONDITION_HPP
Added: trunk/boost/interprocess/sync/windows/named_mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/windows/named_mutex.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,175 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  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/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/windows/sync_utils.hpp>
+#include <boost/interprocess/sync/windows/named_sync.hpp>
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
+#include <boost/interprocess/errors.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+
+
+class windows_named_mutex
+{
+   /// @cond
+
+   //Non-copyable
+   windows_named_mutex();
+   windows_named_mutex(const windows_named_mutex &);
+   windows_named_mutex &operator=(const windows_named_mutex &);
+   /// @endcond
+
+   public:
+   windows_named_mutex(create_only_t, const char *name, const permissions &perm = permissions());
+
+   windows_named_mutex(open_or_create_t, const char *name, const permissions &perm = permissions());
+
+   windows_named_mutex(open_only_t, const char *name);
+
+   ~windows_named_mutex();
+
+   void unlock();
+   void lock();
+   bool try_lock();
+   bool timed_lock(const boost::posix_time::ptime &abs_time);
+
+   static bool remove(const char *name);
+
+   /// @cond
+   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
+      {  return 0u;   }
+
+      virtual const void *buffer_with_init_data_to_file()
+      {  return 0; }
+
+      virtual const void *buffer_with_final_data_to_file()
+      {  return 0; }
+
+      virtual void *buffer_to_store_init_data_from_file()
+      {  return 0; }
+
+      virtual bool open(create_enum_t, const char *id_name)
+      {
+         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 void close()
+      {
+         m_mtx_wrapper.close();
+      }
+
+      virtual ~named_mut_callbacks()
+      {}
+
+      private:
+      winapi_mutex_wrapper&     m_mtx_wrapper;
+   };
+   /// @endcond
+};
+
+inline windows_named_mutex::~windows_named_mutex()
+{
+   named_mut_callbacks callbacks(m_mtx_wrapper);
+   m_named_sync.close(callbacks);
+}
+
+inline void windows_named_mutex::dont_close_on_destruction()
+{}
+
+inline windows_named_mutex::windows_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 windows_named_mutex::windows_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 windows_named_mutex::windows_named_mutex(open_only_t, const char *name)
+   : m_mtx_wrapper()
+{
+   named_mut_callbacks callbacks(m_mtx_wrapper);
+   m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
+}
+
+inline void windows_named_mutex::unlock()
+{
+   m_mtx_wrapper.unlock();
+}
+
+inline void windows_named_mutex::lock()
+{
+   m_mtx_wrapper.lock();
+}
+
+inline bool windows_named_mutex::try_lock()
+{
+   return m_mtx_wrapper.try_lock();
+}
+
+inline bool windows_named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
+{
+   return m_mtx_wrapper.timed_lock(abs_time);
+}
+
+inline bool windows_named_mutex::remove(const char *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
\ No newline at end of file
Added: trunk/boost/interprocess/sync/windows/named_recursive_mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/windows/named_recursive_mutex.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,58 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  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 windows_named_recursive_mutex
+   //Windows mutexes based on CreateMutex are already recursive...
+   : public windows_named_mutex
+{
+   /// @cond
+
+   //Non-copyable
+   windows_named_recursive_mutex();
+   windows_named_recursive_mutex(const windows_named_mutex &);
+   windows_named_recursive_mutex &operator=(const windows_named_mutex &);
+   /// @endcond
+
+   public:
+   windows_named_recursive_mutex(create_only_t, const char *name, const permissions &perm = permissions())
+      : windows_named_mutex(create_only_t(), name, perm)
+   {}
+
+   windows_named_recursive_mutex(open_or_create_t, const char *name, const permissions &perm = permissions())
+      : windows_named_mutex(open_or_create_t(), name, perm)
+   {}
+
+   windows_named_recursive_mutex(open_only_t, const char *name)
+      : windows_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
Added: trunk/boost/interprocess/sync/windows/named_semaphore.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/windows/named_semaphore.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,175 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  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/detail/posix_time_types_wrk.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 windows_named_semaphore
+{
+   /// @cond
+
+   //Non-copyable
+   windows_named_semaphore();
+   windows_named_semaphore(const windows_named_semaphore &);
+   windows_named_semaphore &operator=(const windows_named_semaphore &);
+   /// @endcond
+
+   public:
+   windows_named_semaphore(create_only_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
+
+   windows_named_semaphore(open_or_create_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
+
+   windows_named_semaphore(open_only_t, const char *name);
+
+   ~windows_named_semaphore();
+
+   void post();
+   void wait();
+   bool try_wait();
+   bool timed_wait(const boost::posix_time::ptime &abs_time);
+
+   static bool remove(const char *name);
+
+   /// @cond
+   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
+      {  return sizeof(sem_count_t);   }
+
+      virtual const void *buffer_with_final_data_to_file()
+      {  return &m_sem_count; }
+
+      virtual const void *buffer_with_init_data_to_file()
+      {  return &m_sem_count; }
+
+      virtual void *buffer_to_store_init_data_from_file()
+      {  return &m_sem_count; }
+
+      virtual bool open(create_enum_t, const char *id_name)
+      {
+         std::string aux_str  = "Global\\bipc.sem.";
+         aux_str += id_name;
+         //
+         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);
+      }
+
+      virtual void close()
+      {
+         m_sem_wrapper.close();
+      }
+
+      virtual ~named_sem_callbacks()
+      {}
+
+      private:
+      sem_count_t m_sem_count;
+      winapi_semaphore_wrapper&     m_sem_wrapper;
+   };
+
+   /// @endcond
+};
+
+inline windows_named_semaphore::~windows_named_semaphore()
+{
+   named_sem_callbacks callbacks(m_sem_wrapper, m_sem_wrapper.value());
+   m_named_sync.close(callbacks);
+}
+
+inline void windows_named_semaphore::dont_close_on_destruction()
+{}
+
+inline windows_named_semaphore::windows_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 windows_named_semaphore::windows_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 windows_named_semaphore::windows_named_semaphore(open_only_t, const char *name)
+   : m_sem_wrapper()
+{
+   named_sem_callbacks callbacks(m_sem_wrapper, 0);
+   m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
+}
+
+inline void windows_named_semaphore::post()
+{
+   m_sem_wrapper.post();
+}
+
+inline void windows_named_semaphore::wait()
+{
+   m_sem_wrapper.wait();
+}
+
+inline bool windows_named_semaphore::try_wait()
+{
+   return m_sem_wrapper.try_wait();
+}
+
+inline bool windows_named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
+{
+   return m_sem_wrapper.timed_wait(abs_time);
+}
+
+inline bool windows_named_semaphore::remove(const char *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
Added: trunk/boost/interprocess/sync/windows/named_sync.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/windows/named_sync.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,215 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  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/tmp_dir_helpers.hpp>
+#include <boost/interprocess/sync/windows/sync_utils.hpp>
+#include <boost/interprocess/errors.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <string>
+#include <cassert>
+
+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 void close() = 0;
+   virtual ~windows_named_sync_interface() = 0;
+};
+
+inline windows_named_sync_interface::~windows_named_sync_interface()
+{}
+
+class windows_named_sync
+{
+   /// @cond
+
+   //Non-copyable
+   windows_named_sync(const windows_named_sync &);
+   windows_named_sync &operator=(const windows_named_sync &);
+   /// @endcond
+
+   public:
+   windows_named_sync();
+   void open_or_create(create_enum_t creation_type, const char *name, const permissions &perm, windows_named_sync_interface &sync_interface);
+   void close(windows_named_sync_interface &sync_interface);
+
+   static bool remove(const char *name);
+
+   /// @cond
+   private:
+   void *m_file_hnd;
+
+   /// @endcond
+};
+
+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();
+   const std::size_t sizeof_file_info = sizeof(sync_id::internal_type) + buflen;
+   winapi::interprocess_overlapped overlapped;
+   if(winapi::lock_file_ex
+      (m_file_hnd, winapi::lockfile_exclusive_lock, 0, sizeof_file_info, 0, &overlapped)){
+      if(winapi::set_file_pointer_ex(m_file_hnd, sizeof(sync_id::internal_type), 0, winapi::file_begin)){
+         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();
+   if(m_file_hnd != winapi::invalid_handle_value){
+      winapi::close_handle(m_file_hnd);
+      m_file_hnd = winapi::invalid_handle_value;
+   }
+}
+
+inline void windows_named_sync::open_or_create
+   ( create_enum_t creation_type
+   , const char *name
+   , const permissions &perm
+   , 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
+   {
+      create_tmp_and_clean_old_and_get_filename(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();
+         const std::size_t sizeof_file_info = sizeof(unique_id_val) + buflen;
+         winapi::interprocess_overlapped overlapped;
+         if(winapi::lock_file_ex
+            (m_file_hnd, winapi::lockfile_exclusive_lock, 0, sizeof_file_info, 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;
+               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;
+                  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);
+                  assert(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
+                  char 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
+            err = system_error_code();
+
+            //If this fails we have no possible rollback so don't check the return
+            if(!winapi::unlock_file_ex(m_file_hnd, 0, sizeof_file_info, 0, &overlapped)){
+               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)
+{
+   try{
+      //Make sure a temporary path is created for shared memory
+      std::string semfile;
+      ipcdetail::tmp_filename(name, semfile);
+      return winapi::unlink_file(semfile.c_str());
+   }
+   catch(...){
+      return false;
+   }
+}
+
+}  //namespace ipcdetail {
+}  //namespace interprocess {
+}  //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif   //BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
Modified: trunk/boost/interprocess/sync/windows/semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/windows/semaphore.hpp	(original)
+++ trunk/boost/interprocess/sync/windows/semaphore.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -19,8 +19,9 @@
 #include <boost/interprocess/detail/workaround.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 #include <boost/interprocess/detail/win32_api.hpp>
-#include <boost/interprocess/detail/intermodule_singleton.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>
 
 
@@ -50,7 +51,7 @@
    : id_()
 {
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
+      windows_intermodule_singleton<sync_handles>::get();
    //Force smeaphore creation with the initial count
    bool open_or_created;
    handles.obtain_semaphore(this->id_, initialCount, &open_or_created);
@@ -63,69 +64,43 @@
 inline windows_semaphore::~windows_semaphore() 
 {
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
+      windows_intermodule_singleton<sync_handles>::get();
    handles.destroy_handle(this->id_);
 }
 
 inline void windows_semaphore::wait(void)
 {
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
+      windows_intermodule_singleton<sync_handles>::get();
    //This can throw
-   void *hnd = handles.obtain_semaphore(this->id_, 0);
-   unsigned long ret = winapi::wait_for_single_object(hnd, winapi::infinite_time);
-   if(ret == winapi::wait_failed){
-      error_info err(winapi::get_last_error());
-      throw interprocess_exception(err);
-   }
+   winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+   sem.wait();
 }
 
 inline bool windows_semaphore::try_wait(void)
 {
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
+      windows_intermodule_singleton<sync_handles>::get();
    //This can throw
-   void *hnd = handles.obtain_semaphore(this->id_, 0);
-   unsigned long ret = winapi::wait_for_single_object(hnd, 0);
-   if(ret == winapi::wait_failed){
-      error_info err(winapi::get_last_error());
-      throw interprocess_exception(err);
-   }
-   return ret != winapi::wait_timeout;
+   winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+   return sem.try_wait();
 }
 
 inline bool windows_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
 {
-   if(abs_time == boost::posix_time::pos_infin){
-      this->wait();
-      return true;
-   }
-   boost::posix_time::ptime now
-      = boost::posix_time::microsec_clock::universal_time();
-
-   unsigned long ms = (unsigned long)(abs_time-now).total_milliseconds();
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
+      windows_intermodule_singleton<sync_handles>::get();
    //This can throw
-   void *hnd = handles.obtain_semaphore(this->id_, 0);
-   unsigned long ret = winapi::wait_for_single_object(hnd, ms);
-   if(ret == winapi::wait_failed){
-      error_info err(winapi::get_last_error());
-      throw interprocess_exception(err);
-   }
-   return ret != winapi::wait_timeout;
+   winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+   return sem.timed_wait(abs_time);
 }
 
 inline void windows_semaphore::post(long release_count)
 {
    sync_handles &handles =
-      intermodule_singleton<sync_handles>::get();
-   //This can throw
-   void *hnd = handles.obtain_semaphore(this->id_, 0);
-   long prev_count;
-   int ret = winapi::release_semaphore(hnd, release_count, &prev_count);
-   (void)ret;
-   assert(ret);
+      windows_intermodule_singleton<sync_handles>::get();
+   winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+   sem.post(release_count);
 }
 
 }  //namespace ipcdetail {
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-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -21,6 +21,8 @@
 #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 <cstddef>
 
@@ -32,6 +34,7 @@
 {
    const std::size_t need_mem = mem_length*2+1;
    if(out_length < need_mem){
+      out_length = need_mem;
       return false;
    }
 
@@ -51,10 +54,14 @@
 
 struct sync_id
 {
+   typedef __int64 internal_type;
+   internal_type rand;
+
    sync_id()
    {  winapi::query_performance_counter(&rand);  }
 
-   __int64 rand;
+   explicit sync_id(internal_type val)
+   {  rand = val;  }
 
    friend std::size_t hash_value(const sync_id &m)
    {  return boost::hash_value(m.rand);  }
@@ -62,16 +69,7 @@
    friend bool operator==(const sync_id &l, const sync_id &r)
    {  return l.rand == r.rand;  }
 };
-/*
-#define BOOST_NO_LONG_LONG ss
-
-#if defined(BOOST_NO_LONG_LONG)
 
-#error "defined(BOOST_NO_LONG_LONG)"
-#else
-#error "NOT defined(BOOST_NO_LONG_LONG)"
-#endif
-*/
 class sync_handles
 {
    public:
@@ -108,20 +106,24 @@
    {
       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;
+      sem_wrapper.open_or_create(name, (long)initial_count, unrestricted_security);
+      erase_and_throw_if_error(sem_wrapper.handle(), id);
+      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);
+      erase_and_throw_if_error(mtx_wrapper.handle(), id);
+      return mtx_wrapper.release();
    }
 
    public:
@@ -158,7 +160,6 @@
    }
 
    private:
-   winapi::interprocess_all_access_security unrestricted_security;
    spin_mutex mtx_;
    map_type map_;
 };
Added: trunk/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,163 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  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/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/errors.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+class winapi_mutex_functions
+{
+   /// @cond
+
+   //Non-copyable
+   winapi_mutex_functions(const winapi_mutex_functions &);
+   winapi_mutex_functions &operator=(const winapi_mutex_functions &);
+   /// @endcond
+
+   public:
+   winapi_mutex_functions(void *mtx_hnd)
+      : m_mtx_hnd(mtx_hnd)
+   {}
+
+   void unlock()
+   {
+      winapi::release_mutex(m_mtx_hnd);
+   }
+
+   void lock()
+   {
+      if(winapi::wait_for_single_object(m_mtx_hnd, winapi::infinite_time) != winapi::wait_object_0){
+         error_info err = system_error_code();
+         throw interprocess_exception(err);
+      }
+   }
+
+   bool try_lock()
+   {
+      unsigned long ret = winapi::wait_for_single_object(m_mtx_hnd, 0);
+      if(ret == winapi::wait_object_0){
+         return true;
+      }
+      else if(ret == winapi::wait_timeout){
+         return false;
+      }
+      else{
+         error_info err = system_error_code();
+         throw interprocess_exception(err);
+      }
+   }
+
+   bool timed_lock(const boost::posix_time::ptime &abs_time)
+   {
+      if(abs_time == boost::posix_time::pos_infin){
+         this->lock();
+         return true;
+      }
+
+      unsigned long ret = winapi::wait_for_single_object
+         (m_mtx_hnd, (abs_time - microsec_clock::universal_time()).total_milliseconds());
+      if(ret == winapi::wait_object_0){
+         return true;
+      }
+      else if(ret == winapi::wait_timeout){
+         return false;
+      }
+      else{
+         error_info err = system_error_code();
+         throw interprocess_exception(err);
+      }
+   }
+
+   /// @cond
+   protected:
+   void *m_mtx_hnd;
+   /// @endcond
+};
+
+//Swappable mutex wrapper
+class winapi_mutex_wrapper
+   : public winapi_mutex_functions
+{
+   /// @cond
+
+   //Non-copyable
+   winapi_mutex_wrapper(const winapi_mutex_wrapper &);
+   winapi_mutex_wrapper &operator=(const winapi_mutex_wrapper &);
+   /// @endcond
+
+   public:
+   winapi_mutex_wrapper(void *mtx_hnd = winapi::invalid_handle_value)
+      : winapi_mutex_functions(mtx_hnd)
+   {}
+
+   ~winapi_mutex_wrapper()
+   {  this->close(); }
+
+   void *release()
+   {
+      void *hnd = m_mtx_hnd;
+      m_mtx_hnd = winapi::invalid_handle_value;
+      return hnd;
+   }
+
+   void *handle() const
+   {  return m_mtx_hnd; }
+
+   bool open_or_create(const char *name, const permissions &perm)
+   {
+      if(m_mtx_hnd == winapi::invalid_handle_value){
+         m_mtx_hnd = winapi::open_or_create_mutex
+            ( name
+            , false
+            , (winapi::interprocess_security_attributes*)perm.get_permissions()
+            );
+         return m_mtx_hnd != winapi::invalid_handle_value;
+      }
+      else{
+         return false;
+      }
+   }   
+
+   void close()
+   {
+      if(m_mtx_hnd != winapi::invalid_handle_value){
+         winapi::close_handle(m_mtx_hnd);
+         m_mtx_hnd = winapi::invalid_handle_value;
+      }
+   }
+
+   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
Added: trunk/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp	2012-04-11 02:27:48 EDT (Wed, 11 Apr 2012)
@@ -0,0 +1,176 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (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
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  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/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/errors.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+class winapi_semaphore_functions
+{
+   /// @cond
+
+   //Non-copyable
+   winapi_semaphore_functions(const winapi_semaphore_functions &);
+   winapi_semaphore_functions &operator=(const winapi_semaphore_functions &);
+   /// @endcond
+
+   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()
+   {
+      if(winapi::wait_for_single_object(m_sem_hnd, winapi::infinite_time) != winapi::wait_object_0){
+         error_info err = system_error_code();
+         throw interprocess_exception(err);
+      }
+   }
+
+   bool try_wait()
+   {
+      unsigned long ret = winapi::wait_for_single_object(m_sem_hnd, 0);
+      if(ret == winapi::wait_object_0){
+         return true;
+      }
+      else if(ret == winapi::wait_timeout){
+         return false;
+      }
+      else{
+         error_info err = system_error_code();
+         throw interprocess_exception(err);
+      }
+   }
+
+   bool timed_wait(const boost::posix_time::ptime &abs_time)
+   {
+      if(abs_time == boost::posix_time::pos_infin){
+         this->wait();
+         return true;
+      }
+
+      unsigned long ret = winapi::wait_for_single_object
+         (m_sem_hnd, (abs_time - microsec_clock::universal_time()).total_milliseconds());
+      if(ret == winapi::wait_object_0){
+         return true;
+      }
+      else if(ret == winapi::wait_timeout){
+         return false;
+      }
+      else{
+         error_info err = system_error_code();
+         throw interprocess_exception(err);
+      }
+   }
+
+   unsigned int 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){
+         return 0;
+      }
+      return info.count;
+   }
+
+   /// @cond
+   protected:
+   void *m_sem_hnd;
+   /// @endcond
+};
+
+
+//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:
+
+   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; }
+
+   bool open_or_create(const char *name, long sem_count, const permissions &perm)
+   {
+      if(m_sem_hnd == winapi::invalid_handle_value){
+         m_sem_hnd = winapi::open_or_create_semaphore
+            ( name
+            , sem_count
+            , (std::numeric_limits<long>::max)()
+            , (winapi::interprocess_security_attributes*)perm.get_permissions()
+            );
+         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