$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r64333 - trunk/boost/interprocess/detail
From: igaztanaga_at_[hidden]
Date: 2010-07-25 12:39:27
Author: igaztanaga
Date: 2010-07-25 12:39:26 EDT (Sun, 25 Jul 2010)
New Revision: 64333
URL: http://svn.boost.org/trac/boost/changeset/64333
Log:
Changes for Boost 1.45
Added:
   trunk/boost/interprocess/detail/robust_emulation.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/interprocess/detail/os_file_functions.hpp        |   124 ++++++                                  
   trunk/boost/interprocess/detail/os_thread_functions.hpp      |    30 +                                       
   trunk/boost/interprocess/detail/posix_time_types_wrk.hpp     |     3                                         
   trunk/boost/interprocess/detail/preprocessor.hpp             |    52 ++                                      
   trunk/boost/interprocess/detail/tmp_dir_helpers.hpp          |    14                                         
   trunk/boost/interprocess/detail/transform_iterator.hpp       |    21 +                                       
   trunk/boost/interprocess/detail/win32_api.hpp                |   642 ++++++++++++++++++++++++++++++++++++++- 
   trunk/boost/interprocess/detail/workaround.hpp               |     2                                         
   trunk/boost/interprocess/detail/xsi_shared_memory_device.hpp |     6                                         
   9 files changed, 833 insertions(+), 61 deletions(-)
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	2010-07-25 12:39:26 EDT (Sun, 25 Jul 2010)
@@ -14,6 +14,8 @@
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
 #include <boost/interprocess/errors.hpp>
+#include <boost/interprocess/permissions.hpp>
+
 #include <string>
 
 #if (defined BOOST_INTERPROCESS_WINDOWS)
@@ -53,6 +55,7 @@
 typedef enum { read_only      = winapi::generic_read
              , read_write     = winapi::generic_read | winapi::generic_write
              , copy_on_write
+             , read_private
              , invalid_mode   = 0xffff 
              } mode_t;
 
@@ -83,34 +86,36 @@
 {  return hnd.handle; }
 
 inline bool create_directory(const char *path)
-{  return winapi::create_directory(path, 0); }
+{  return winapi::create_directory(path); }
 
 inline const char *get_temporary_path()
 {  return std::getenv("TMP"); }
 
 
 inline file_handle_t create_new_file
-   (const char *name, mode_t mode = read_write, bool temporary = false)
+   (const char *name, mode_t mode, const permissions & perm, bool temporary = false)
 {  
    unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
    return winapi::create_file
-      (name, (unsigned int)mode, winapi::create_new, attr);  
+      ( name, (unsigned int)mode, winapi::create_new, attr
+      , (winapi::interprocess_security_attributes*)perm.get_permissions());  
 }
 
 inline file_handle_t create_or_open_file
-   (const char *name, mode_t mode = read_write, bool temporary = false)
+   (const char *name, mode_t mode, const permissions & perm, bool temporary = false)
 {  
    unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
    return winapi::create_file
-      (name, (unsigned int)mode, winapi::open_always, attr);  
+      ( name, (unsigned int)mode, winapi::open_always, attr
+      , (winapi::interprocess_security_attributes*)perm.get_permissions());  
 }
 
 inline file_handle_t open_existing_file
-   (const char *name, mode_t mode = read_write, bool temporary = false)
+   (const char *name, mode_t mode, bool temporary = false)
 {  
    unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
    return winapi::create_file
-      (name, (unsigned int)mode, winapi::open_existing, attr);  
+      (name, (unsigned int)mode, winapi::open_existing, attr, 0);  
 }
 
 inline bool delete_file(const char *name)
@@ -299,6 +304,44 @@
    return delete_subdirectories_recursive(refcstrRootDirectory, dont_delete_this, 0u);
 }
 
+
+template<class Function>
+inline bool for_each_file_in_dir(const char *dir, Function f)
+{
+   void *             hFile;                       // Handle to directory
+   winapi::win32_find_data_t  FileInformation;     // File information
+
+   //Get base directory
+   std::string str(dir);
+   const std::size_t base_root_dir_len = str.size();
+
+   //Find all files and directories
+   str  +=  "\\*.*";
+   hFile = winapi::find_first_file(str.c_str(), &FileInformation);
+   if(hFile != winapi::invalid_handle_value){
+      do{   //Now loop every file
+         str.erase(base_root_dir_len);
+         //If it's not "." or ".." skip it
+         if(FileInformation.cFileName[0] != '.'){
+            str += "\\";   str += FileInformation.cFileName;
+            //If it's a file, apply erase logic
+            if(!(FileInformation.dwFileAttributes & winapi::file_attribute_directory)){
+               f(str.c_str(), FileInformation.cFileName);
+            }
+         }
+      //Go to the next file
+      } while(winapi::find_next_file(hFile, &FileInformation) == 1);
+
+      // Close handle and see if the loop has ended with an error
+      winapi::find_close(hFile);
+      if(winapi::get_last_error() != winapi::error_no_more_files){
+         return false;
+      }
+   }
+   return true;
+}
+
+
 #else    //#if (defined BOOST_INTERPROCESS_WINDOWS)
 
 typedef int       file_handle_t;
@@ -313,6 +356,7 @@
 typedef enum { read_only      = O_RDONLY
              , read_write     = O_RDWR
              , copy_on_write
+             , read_private
              , invalid_mode   = 0xffff 
              } mode_t;
 
@@ -335,7 +379,7 @@
 {  return hnd.handle; }
 
 inline bool create_directory(const char *path)
-{  return ::mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0; }
+{  return ::mkdir(path, 0777) == 0 && ::chmod(path, 0777) == 0; }
 
 inline const char *get_temporary_path()
 {
@@ -351,24 +395,32 @@
 }
 
 inline file_handle_t create_new_file
-   (const char *name, mode_t mode = read_write, bool temporary = false)
+   (const char *name, mode_t mode, const permissions & perm, bool temporary = false)
 {  
    (void)temporary;
-   return ::open(name, ((int)mode) | O_EXCL | O_CREAT, S_IRWXG | S_IRWXO | S_IRWXU); 
+   int ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
+   if(ret >= 0){
+      ::fchmod(ret, perm.get_permissions());
+   }
+   return ret;
 }
 
 inline file_handle_t create_or_open_file
-   (const char *name, mode_t mode = read_write, bool temporary = false)
+   (const char *name, mode_t mode, const permissions & perm, bool temporary = false)
 {  
    (void)temporary;
-   return ::open(name, ((int)mode) | O_CREAT, S_IRWXG | S_IRWXO | S_IRWXU); 
+   int ret = ::open(name, ((int)mode) | O_CREAT, perm.get_permissions());
+   if(ret >= 0){
+      ::fchmod(ret, perm.get_permissions());
+   }
+   return ret;
 }
 
 inline file_handle_t open_existing_file
-   (const char *name, mode_t mode = read_write, bool temporary = false)
+   (const char *name, mode_t mode, bool temporary = false)
 {  
    (void)temporary;
-   return ::open(name, (int)mode, S_IRWXG | S_IRWXO | S_IRWXU); 
+   return ::open(name, (int)mode, 0666);
 }
 
 inline bool delete_file(const char *name)
@@ -388,7 +440,7 @@
 }
 
 inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos)
-{  return off == ::lseek(hnd, off, (int)pos); }
+{  return ((off_t)(-1)) != ::lseek(hnd, off, (int)pos); }
 
 inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
 {  
@@ -543,6 +595,48 @@
    return std::remove(refcstrRootDirectory.c_str()) ? false : true;
 }
 
+template<class Function>
+inline bool for_each_file_in_dir(const char *dir, Function f)
+{
+   std::string refcstrRootDirectory(dir);
+
+   DIR *d = opendir(refcstrRootDirectory.c_str());
+   if(!d) {
+      return false;
+   }
+
+   struct dir_close
+   {
+      DIR *d_;
+      dir_close(DIR *d) : d_(d) {}
+      ~dir_close() { ::closedir(d_); }
+   } dc(d); (void)dc;
+
+   struct ::dirent *de;
+   struct ::stat st;
+   std::string fn;
+
+   while((de=::readdir(d))) {
+      if( de->d_name[0] == '.' && ( de->d_name[1] == '\0'
+            || (de->d_name[1] == '.' && de->d_name[2] == '\0' )) ){
+         continue;
+      }
+      fn = refcstrRootDirectory;
+      fn += '/';
+      fn += de->d_name;
+
+      if(::stat(fn.c_str(), & st)) {
+         return false;
+      }
+      //If it's a file, apply erase logic
+      if(!S_ISDIR(st.st_mode)) {
+         f(fn.c_str(), de->d_name);
+      }
+   }
+   return true;
+}
+
+
 //This function erases all the subdirectories of a directory except the one pointed by "dont_delete_this"
 inline bool delete_subdirectories(const std::string &refcstrRootDirectory, const char *dont_delete_this)
 {
Modified: trunk/boost/interprocess/detail/os_thread_functions.hpp
==============================================================================
--- trunk/boost/interprocess/detail/os_thread_functions.hpp	(original)
+++ trunk/boost/interprocess/detail/os_thread_functions.hpp	2010-07-25 12:39:26 EDT (Sun, 25 Jul 2010)
@@ -13,6 +13,8 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/streams/bufferstream.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 
 #if (defined BOOST_INTERPROCESS_WINDOWS)
 #  include <boost/interprocess/detail/win32_api.hpp>
@@ -78,6 +80,20 @@
    return get_invalid_thread_id();
 }
 
+inline long double get_current_process_creation_time()
+{
+   winapi::interprocess_filetime CreationTime, ExitTime, KernelTime, UserTime;
+
+   get_process_times
+      ( winapi::get_current_process(), &CreationTime, &ExitTime, &KernelTime, &UserTime);
+
+   typedef long double ldouble_t;
+   const ldouble_t resolution = (100.0l/1000000000.0l);
+   return CreationTime.dwHighDateTime*(ldouble_t(1u<<31u)*2.0l*resolution) +
+              CreationTime.dwLowDateTime*resolution;
+}
+
+
 #else    //#if (defined BOOST_INTERPROCESS_WINDOWS)
 
 typedef pthread_t OS_thread_id_t;
@@ -160,8 +176,22 @@
    return OS_systemwide_thread_id_t(get_invalid_process_id(), get_invalid_thread_id());
 }
 
+inline long double get_current_process_creation_time()
+{ return 0.0L; }
+
 #endif   //#if (defined BOOST_INTERPROCESS_WINDOWS)
 
+typedef char pid_str_t[sizeof(OS_process_id_t)*3+1];
+
+inline void get_pid_str(pid_str_t &pid_str, OS_process_id_t pid)
+{
+   bufferstream bstream(pid_str, sizeof(pid_str));
+   bstream << pid << std::ends;
+}
+
+inline void get_pid_str(pid_str_t &pid_str)
+{  get_pid_str(pid_str, get_current_process_id());  }
+
 }  //namespace detail{
 }  //namespace interprocess {
 }  //namespace boost {
Modified: trunk/boost/interprocess/detail/posix_time_types_wrk.hpp
==============================================================================
--- trunk/boost/interprocess/detail/posix_time_types_wrk.hpp	(original)
+++ trunk/boost/interprocess/detail/posix_time_types_wrk.hpp	2010-07-25 12:39:26 EDT (Sun, 25 Jul 2010)
@@ -20,9 +20,8 @@
 #endif   //#ifndef WIN32_LEAN_AND_MEAN
 #endif   //#ifdef _WIN32
 
-//#include <boost/date_time/posix_time/ptime.hpp>
-//#include <boost/date_time/microsec_time_clock.hpp>
 #include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
 
 namespace boost {
 namespace interprocess {
Modified: trunk/boost/interprocess/detail/preprocessor.hpp
==============================================================================
--- trunk/boost/interprocess/detail/preprocessor.hpp	(original)
+++ trunk/boost/interprocess/detail/preprocessor.hpp	2010-07-25 12:39:26 EDT (Sun, 25 Jul 2010)
@@ -15,8 +15,7 @@
 #  pragma once
 #endif
 
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
+#include "config_begin.hpp"
 
 #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
 #error "This file is not needed when perfect forwarding is available"
@@ -36,7 +35,7 @@
 //This cast is ugly but it is necessary until "perfect forwarding"
 //is achieved in C++0x. Meanwhile, if we want to be able to
 //bind rvalues with non-const references, we have to be ugly
-#ifdef BOOST_HAS_RVALUE_REFS
+#ifndef BOOST_NO_RVALUE_REFERENCES
    #define BOOST_INTERPROCESS_PP_PARAM_LIST(z, n, data) \
    BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
    //!
@@ -46,7 +45,7 @@
    //!
 #endif
 
-#ifdef BOOST_HAS_RVALUE_REFS
+#ifndef BOOST_NO_RVALUE_REFERENCES
    #define BOOST_INTERPROCESS_PARAM(U, u) \
    U && u \
    //!
@@ -56,10 +55,22 @@
    //!
 #endif
 
-#ifdef BOOST_HAS_RVALUE_REFS
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+
+#define BOOST_INTERPROCESS_AUX_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) ))           \
+//!
+
+#else
+
 #define BOOST_INTERPROCESS_AUX_PARAM_INIT(z, n, data) \
   BOOST_PP_CAT(m_p, n) (BOOST_PP_CAT(p, n))           \
 //!
+
+#endif
+
 #else
 #define BOOST_INTERPROCESS_AUX_PARAM_INIT(z, n, data) \
   BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
@@ -70,10 +81,23 @@
   BOOST_PP_CAT(++m_p, n)                        \
 //!
 
-#ifdef BOOST_HAS_RVALUE_REFS
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+#define BOOST_INTERPROCESS_AUX_PARAM_DEFINE(z, n, data)  \
+  BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n);            \
+//!
+
+#else
+
 #define BOOST_INTERPROCESS_AUX_PARAM_DEFINE(z, n, data)  \
   BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n);            \
 //!
+
+#endif //defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+
 #else
 #define BOOST_INTERPROCESS_AUX_PARAM_DEFINE(z, n, data)  \
   BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n);             \
@@ -81,13 +105,25 @@
 #endif
 
 #define BOOST_INTERPROCESS_PP_PARAM_FORWARD(z, n, data) \
-boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
+::boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
+//!
+
+#if !defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+#include <boost/interprocess/containers/container/detail/stored_ref.hpp>
+
+#define BOOST_INTERPROCESS_PP_MEMBER_FORWARD(z, n, data) \
+::boost::container::containers_detail::stored_ref< BOOST_PP_CAT(P, n) >::forward( BOOST_PP_CAT(m_p, n) ) \
 //!
 
+#else
+
 #define BOOST_INTERPROCESS_PP_MEMBER_FORWARD(z, n, data) \
-boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
+::boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
 //!
 
+#endif   //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
 #define BOOST_INTERPROCESS_PP_MEMBER_IT_FORWARD(z, n, data) \
 BOOST_PP_CAT(*m_p, n) \
 //!
Added: trunk/boost/interprocess/detail/robust_emulation.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/robust_emulation.hpp	2010-07-25 12:39:26 EDT (Sun, 25 Jul 2010)
@@ -0,0 +1,439 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2010-2010. 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_ROBUST_EMULATION_HPP
+#define BOOST_INTERPROCESS_ROBUST_EMULATION_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/interprocess_mutex.hpp>
+#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
+#include <boost/interprocess/detail/atomic.hpp>
+#include <boost/interprocess/detail/os_file_functions.hpp>
+#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
+#include <boost/interprocess/detail/intermodule_singleton.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <string>
+
+namespace boost{
+namespace interprocess{
+namespace detail{
+
+namespace robust_emulation_helpers {
+
+template<class T>
+class mutex_traits
+{
+   public:
+   static void take_ownership(T &t)
+   {  t.take_ownership(); }
+};
+
+inline void remove_if_can_lock_file(const char *file_path)
+{
+   file_handle_t fhnd = open_existing_file(file_path, read_write);
+
+   if(fhnd != invalid_file()){
+      bool acquired;
+      if(try_acquire_file_lock(fhnd, acquired) && acquired){
+         delete_file(file_path);
+      }
+      close_file(fhnd);
+   }
+}
+
+inline const char *robust_lock_subdir_path()
+{  return "robust"; }
+
+inline const char *robust_lock_prefix()
+{  return "lck"; }
+
+inline void robust_lock_path(std::string &s)
+{
+   tmp_folder(s);
+   s += "/";
+   s += robust_lock_subdir_path();
+}
+
+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
+      (robust_lock_subdir_path(), robust_lock_prefix(), pid, s);
+}
+
+//This class will be a intermodule_singleton. The constructor will create
+//a lock file, the destructor will erase it.
+//
+//We should take in care that another process might be erasing unlocked
+//files while creating this one, so there are some race conditions we must
+//take in care to guarantee some robustness.
+class robust_mutex_lock_file
+{
+   file_handle_t fd;
+   std::string fname;
+   public:
+   robust_mutex_lock_file()
+   {
+      permissions p;
+      p.set_unrestricted();
+      //Remove old lock files of other processes
+      remove_old_robust_lock_files();
+      //Create path and obtain lock file path for this process
+      create_and_get_robust_lock_file_path(fname, get_current_process_id());
+
+      //Now try to open or create the lock file
+      fd = create_or_open_file(fname.c_str(), read_write, p);
+      //If we can't open or create it, then something unrecoverable has happened
+      if(fd == invalid_file()){
+         throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: could not open or create file");
+      }
+
+      //Now we must take in care a race condition with another process
+      //calling "remove_old_robust_lock_files()". No other threads from this
+      //process will be creating the lock file because intermodule_singleton
+      //guarantees this. So let's loop acquiring the lock and checking if we
+      //can't exclusively create the file (if the file is erased by another process
+      //then this exclusive open would fail). If the file can't be exclusively created
+      //then we have correctly open/create and lock the file. If the file can
+      //be exclusively created, then close previous locked file and try again.
+      while(1){
+         bool acquired;
+         if(!try_acquire_file_lock(fd, acquired) || !acquired ){
+            throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: try_acquire_file_lock");
+         }
+         //Creating exclusively must fail with already_exists_error
+         //to make sure we've locked the file and no one has
+         //deleted it between creation and locking
+         file_handle_t fd2 = create_new_file(fname.c_str(), read_write, p);
+         if(fd2 != invalid_file()){
+            close_file(fd);
+            fd = fd2;
+            continue;
+         }
+         //If exclusive creation fails with expected error go ahead
+         else if(error_info(system_error_code()).get_error_code() == already_exists_error){ //must already exist
+            //Leak descriptor to mantain the file locked until the process dies
+            break;
+         }
+         //If exclusive creation fails with unexpected error throw an unrecoverable error
+         else{
+            close_file(fd);
+            throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: create_file filed with unexpected error");
+         }
+      }
+   }   
+
+   ~robust_mutex_lock_file()
+   {
+      //The destructor is guaranteed by intermodule_singleton to be
+      //executed serialized between all threads from current process,
+      //so we just need to close and unlink the file.
+      close_file(fd);
+      //If some other process deletes the file before us after
+      //closing it there should not be any problem.
+      delete_file(fname.c_str());
+   }
+
+   private:
+   //This functor is execute for all files in the lock file directory
+   class other_process_lock_remover
+   {
+      public:
+      void operator()(const char *filepath, const char *filename)
+      {
+         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
+            (filename, robust_lock_prefix(), get_current_process_id(), pid_str)){
+            remove_if_can_lock_file(filepath);
+         }
+      }
+   };
+
+   bool remove_old_robust_lock_files()
+   {
+      std::string refcstrRootDirectory;
+      robust_lock_path(refcstrRootDirectory);
+      return for_each_file_in_dir(refcstrRootDirectory.c_str(), other_process_lock_remover());
+   }
+};
+
+}  //namespace robust_emulation_helpers {
+
+//This is the mutex class. Mutex should follow mutex concept
+//with an additonal "take_ownership()" function to take ownership of the
+//mutex when robust_emulation_mutex determines the previous owner was dead.
+template<class Mutex>
+class robust_emulation_mutex
+{
+   public:
+   static const boost::uint32_t correct_state = 0;
+   static const boost::uint32_t fixing_state  = 1;
+   static const boost::uint32_t broken_state  = 2;
+
+   typedef robust_emulation_helpers::mutex_traits<Mutex> mutex_traits_t;
+
+   robust_emulation_mutex();
+   void lock();
+   bool try_lock();
+   bool timed_lock(const boost::posix_time::ptime &abs_time);
+   void unlock();
+   void consistent();
+   bool previous_owner_dead();
+
+   private:
+   static const unsigned int spin_threshold = 100u;
+   bool lock_own_unique_file();
+   bool robust_check();
+   bool check_if_owner_dead_and_take_ownership_atomically();
+   bool is_owner_dead(boost::uint32_t owner);
+   void owner_to_filename(boost::uint32_t owner, std::string &s);
+   //The real mutex
+   Mutex mtx;
+   //The pid of the owner
+   volatile boost::uint32_t owner;
+   //The state of the mutex (correct, fixing, broken)
+   volatile boost::uint32_t state;
+};
+
+template<class Mutex>
+inline robust_emulation_mutex<Mutex>::robust_emulation_mutex()
+   : mtx(), owner(get_invalid_process_id()), state(correct_state)
+{}
+
+template<class Mutex>
+inline void robust_emulation_mutex<Mutex>::lock()
+{
+   //If the mutex is broken (recovery didn't call consistent()),
+   //then throw an exception
+   if(atomic_read32(&this->state) == broken_state){
+      throw interprocess_exception(lock_error, "Broken id");
+   }
+
+   //This function provokes intermodule_singleton instantiation
+   if(!this->lock_own_unique_file()){
+      throw interprocess_exception(lock_error, "Broken id");
+   }
+
+   //Now the logic. Try to lock, if successful mark the owner
+   //if it fails, start recovery logic
+   unsigned int spin_count = 0;
+   while(1){
+      if (mtx.try_lock()){
+         atomic_write32(&this->owner, get_current_process_id());
+         break;
+      }
+      else{
+         //Do the dead owner checking each spin_threshold lock tries
+         detail::thread_yield();
+         ++spin_count;
+         if(spin_count > spin_threshold){
+            //Check if owner dead and take ownership if possible
+            if(!this->robust_check()){
+               spin_count = 0;
+            }
+            else{
+               break;
+            }
+         }
+      }
+   }
+}
+
+template<class Mutex>
+inline bool robust_emulation_mutex<Mutex>::try_lock()
+{
+   //Same as lock() but without spinning
+   if(atomic_read32(&this->state) == broken_state){
+      throw interprocess_exception(lock_error, "Broken id");
+   }
+
+   if(!this->lock_own_unique_file()){
+      throw interprocess_exception(lock_error, "Broken id");
+   }
+
+   if (mtx.try_lock()){
+      atomic_write32(&this->owner, get_current_process_id());
+      return true;
+   }
+   else{
+      if(!this->robust_check()){
+         return false;
+      }
+      else{
+         return true;
+      }
+   }
+}
+
+template<class Mutex>
+inline bool robust_emulation_mutex<Mutex>::timed_lock
+   (const boost::posix_time::ptime &abs_time)
+{
+   //Same as lock() but with an additional timeout
+   if(abs_time == boost::posix_time::pos_infin){
+      this->lock();
+      return true;
+   }
+   //Obtain current count and target time
+   boost::posix_time::ptime now = microsec_clock::universal_time();
+
+   if(now >= abs_time)
+      return this->try_lock();
+
+   do{
+      if(this->try_lock()){
+         break;
+      }
+      now = microsec_clock::universal_time();
+
+      if(now >= abs_time){
+         return this->try_lock();
+      }
+      // relinquish current time slice
+      detail::thread_yield();
+   }while (true);
+
+   return true;
+}
+
+template<class Mutex>
+inline void robust_emulation_mutex<Mutex>::owner_to_filename(boost::uint32_t owner, std::string &s)
+{
+   robust_emulation_helpers::create_and_get_robust_lock_file_path(s, owner);
+}
+
+template<class Mutex>
+inline bool robust_emulation_mutex<Mutex>::robust_check()
+{
+   //If the old owner was dead, and we've acquired ownership, mark
+   //the mutex as 'fixing'. This means that a "consistent()" is needed
+   //to avoid marking the mutex as "broken" when the mutex is unlocked.
+   if(!this->check_if_owner_dead_and_take_ownership_atomically()){
+      return false;
+   }
+   atomic_write32(&this->state, fixing_state);
+   return true;   
+}
+
+template<class Mutex>
+inline bool robust_emulation_mutex<Mutex>::check_if_owner_dead_and_take_ownership_atomically()
+{
+   boost::uint32_t cur_owner = get_current_process_id();
+   boost::uint32_t old_owner = atomic_read32(&this->owner), old_owner2;
+   //The cas loop guarantees that only one thread from this or another process
+   //will succeed taking ownership
+   do{
+      //Check if owner is dead
+      if(!this->is_owner_dead(old_owner)){
+         return false;
+      }
+      //If it's dead, try to mark this process as the owner in the owner field
+      old_owner2 = old_owner;
+      old_owner = atomic_cas32(&this->owner, cur_owner, old_owner);
+   }while(old_owner2 != old_owner);
+   //If success, we fix mutex internals to assure our ownership
+   mutex_traits_t::take_ownership(mtx);
+   return true;
+}
+
+template<class Mutex>
+inline bool robust_emulation_mutex<Mutex>::is_owner_dead(boost::uint32_t owner)
+{
+   //If owner is an invalid id, then it's clear it's dead
+   if(owner == (boost::uint32_t)get_invalid_process_id()){
+      return true;
+   }
+
+   //Obtain the lock filename of the owner field
+   std::string file;
+   this->owner_to_filename(owner, file);
+
+   //Now the logic is to open and lock it
+   file_handle_t fhnd = open_existing_file(file.c_str(), read_write);
+
+   if(fhnd != invalid_file()){
+      //If we can open the file, lock it.
+      bool acquired;
+      if(try_acquire_file_lock(fhnd, acquired) && acquired){
+         //If locked, just delete the file
+         delete_file(file.c_str());
+         close_file(fhnd);
+         return true;
+      }
+      //If not locked, the owner is suppossed to be still alive
+      close_file(fhnd);
+   }
+   else{
+      //If the lock file does not exist then the owner is dead (a previous cleanup)
+      //function has deleted the file. If there is another reason, then this is
+      //an unrecoverable error
+      if(error_info(system_error_code()).get_error_code() == not_found_error){
+         return true;
+      }
+   }
+   return false;
+}
+
+template<class Mutex>
+inline void robust_emulation_mutex<Mutex>::consistent()
+{
+   //This function supposes the previous state was "fixing"
+   //and the current process holds the mutex
+   if(atomic_read32(&this->state) != fixing_state &&
+      atomic_read32(&this->owner) != (boost::uint32_t)get_current_process_id()){
+      throw interprocess_exception(lock_error, "Broken id");
+   }
+   //If that's the case, just update mutex state
+   atomic_write32(&this->state, correct_state);
+}
+
+template<class Mutex>
+inline bool robust_emulation_mutex<Mutex>::previous_owner_dead()
+{
+   //Notifies if a owner recovery has been performed in the last lock()
+   return atomic_read32(&this->state) == fixing_state;
+};
+
+template<class Mutex>
+inline void robust_emulation_mutex<Mutex>::unlock()
+{
+   //If in "fixing" state, unlock and mark the mutex as unrecoverable
+   //so next locks will fail and all threads will be notified that the
+   //data protected by the mutex was not recoverable.
+   if(atomic_read32(&this->state) == fixing_state){
+      atomic_write32(&this->state, broken_state);
+   }
+   //Write an invalid owner to minimize pid reuse possibility
+   atomic_write32(&this->owner, get_invalid_process_id());
+   mtx.unlock();
+}
+
+template<class Mutex>
+inline bool robust_emulation_mutex<Mutex>::lock_own_unique_file()
+{
+   //This function forces instantiation of the singleton
+   robust_emulation_helpers::robust_mutex_lock_file* dummy = 
+      &detail::intermodule_singleton
+         <robust_emulation_helpers::robust_mutex_lock_file>::get();
+   return dummy != 0;
+}
+
+}  //namespace detail{
+}  //namespace interprocess{
+}  //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif
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	2010-07-25 12:39:26 EDT (Sun, 25 Jul 2010)
@@ -37,10 +37,8 @@
 #if defined (BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME)
 inline void get_bootstamp(std::string &s, bool add = false)
 {
-   char bootstamp[winapi::BootstampLength*2+1];
-   std::size_t bootstamp_length = winapi::BootstampLength*2;
-   winapi::get_boot_time_str(bootstamp, bootstamp_length);
-   bootstamp[winapi::BootstampLength*2] = 0;
+   std::string bootstamp;
+   winapi::get_last_bootup_time(bootstamp);
    if(add){
       s += bootstamp;
    }
@@ -118,7 +116,7 @@
    tmp_name += filename;
 }
 
-inline void create_tmp_dir(std::string &tmp_name)
+inline void create_tmp_and_clean_old(std::string &tmp_name)
 {
    //First get the temp directory
    std::string root_tmp_name;
@@ -146,12 +144,14 @@
    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;
    #endif
 }
 
-inline void create_tmp_dir_and_get_filename(const char *filename, std::string &tmp_name)
+inline void create_tmp_and_clean_old_and_get_filename(const char *filename, std::string &tmp_name)
 {
-   create_tmp_dir(tmp_name);
+   create_tmp_and_clean_old(tmp_name);
    tmp_filename(filename, tmp_name);
 }
 
Modified: trunk/boost/interprocess/detail/transform_iterator.hpp
==============================================================================
--- trunk/boost/interprocess/detail/transform_iterator.hpp	(original)
+++ trunk/boost/interprocess/detail/transform_iterator.hpp	2010-07-25 12:39:26 EDT (Sun, 25 Jul 2010)
@@ -50,7 +50,7 @@
       :  m_value(px)
    {}
 
-   T* operator->() const { return &m_value; }
+   T* operator->() const { return const_cast<T*>(&m_value); }
    // This function is needed for MWCW and BCC, which won't call operator->
    // again automatically per 13.3.1.2 para 8
 //   operator T*() const { return &m_value; }
@@ -87,13 +87,25 @@
       return result;
    }
 
+   transform_iterator& operator--() 
+   { decrement();   return *this;   }
+
+   transform_iterator operator--(int)
+   {
+      transform_iterator result (*this);
+      decrement();
+      return result;
+   }
+
    friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
    { return i.equal(i2); }
 
    friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
    { return !(i == i2); }
 
-/*
+   friend bool operator< (const transform_iterator& i, const transform_iterator& i2)
+   { return i < i2; }
+
    friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
    { return i2 < i; }
 
@@ -102,7 +114,7 @@
 
    friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
    { return !(i < i2); }
-*/
+
    friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
    { return i2.distance_to(i); }
 
@@ -129,6 +141,9 @@
    typename UnaryFunction::result_type operator*() const
    { return dereference(); }
 
+   typename UnaryFunction::result_type operator[](typename Iterator::difference_type off) const
+   { return UnaryFunction::operator()(m_it[off]); }
+
    operator_arrow_proxy<typename UnaryFunction::result_type>
       operator->() const
    { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference());  }
Modified: trunk/boost/interprocess/detail/win32_api.hpp
==============================================================================
--- trunk/boost/interprocess/detail/win32_api.hpp	(original)
+++ trunk/boost/interprocess/detail/win32_api.hpp	2010-07-25 12:39:26 EDT (Sun, 25 Jul 2010)
@@ -16,11 +16,14 @@
 #include <cstddef>
 #include <cstring>
 #include <string>
+#include <vector>
 #include <memory>
 
 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
 #  pragma once
 #  pragma comment( lib, "advapi32.lib" )
+#  pragma comment( lib, "oleaut32.lib" )
+#  pragma comment( lib, "Ole32.lib" )
 #endif
 
 #if (defined BOOST_INTERPROCESS_WINDOWS)
@@ -30,6 +33,7 @@
 # error "This file can only be included in Windows OS"
 #endif
 
+
 //The structures used in Interprocess with the
 //same binary interface as windows ones
 namespace boost {
@@ -154,16 +158,394 @@
 static void * const  hkey_local_machine = (void*)(unsigned long*)(long)(0x80000002);
 static unsigned long key_query_value    = 0x0001;
 
+//COM API
+const long RPC_C_AUTHN_LEVEL_PKT_IG = 4;
+const long RPC_C_IMP_LEVEL_IMPERSONATE_IG = 3;
+const long EOAC_NONE_IG = 0;
+const long CLSCTX_INPROC_SERVER_IG	= 0x1;
+const long CLSCTX_LOCAL_SERVER_IG	= 0x4;
+const long WBEM_FLAG_RETURN_IMMEDIATELY_IG = 0x10;
+const long WBEM_INFINITE_IG = 0xffffffff;
+
 }  //namespace winapi {
 }  //namespace interprocess  {
 }  //namespace boost  {
 
-#if !defined( BOOST_USE_WINDOWS_H )
 
 namespace boost  {
 namespace interprocess  {
 namespace winapi {
 
+struct GUID_IG
+{
+   unsigned long  Data1;
+   unsigned short Data2;
+   unsigned short Data3;
+   unsigned char  Data4[8];
+};
+
+const GUID_IG CLSID_WbemAdministrativeLocator =
+   { 0xcb8555cc, 0x9128, 0x11d1, {0xad, 0x9b, 0x00, 0xc0, 0x4f, 0xd8, 0xfd, 0xff}};
+
+const GUID_IG IID_IUnknown = { 0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
+
+struct wchar_variant
+{
+   unsigned long  long dummy;
+   union value_t{
+      wchar_t *pbstrVal;
+      unsigned long  long dummy;
+   } value;
+};
+
+   struct IUnknown_IG
+   {
+      public:
+      virtual long __stdcall QueryInterface( 
+            /* [in] */ const GUID_IG &riid,
+            /* [iid_is][out] */ void **ppvObject) = 0;
+      
+      virtual unsigned long __stdcall AddRef( void) = 0;
+      
+      virtual unsigned long __stdcall Release( void) = 0;
+   };
+
+struct IWbemClassObject_IG : public IUnknown_IG
+{
+   public:
+   virtual long __stdcall GetQualifierSet( 
+      /* [out] */ void **ppQualSet) = 0;
+   
+   virtual long __stdcall Get( 
+      /* [string][in] */ const wchar_t * wszName,
+      /* [in] */ long lFlags,
+      /* [unique][in][out] */ wchar_variant *pVal,
+      /* [unique][in][out] */ long *pType,
+      /* [unique][in][out] */ long *plFlavor) = 0;
+   
+   virtual long __stdcall Put( 
+      /* [string][in] */ const wchar_t * wszName,
+      /* [in] */ long lFlags,
+      /* [in] */ wchar_variant *pVal,
+      /* [in] */ long Type) = 0;
+   
+   virtual long __stdcall Delete( 
+      /* [string][in] */ const wchar_t * wszName) = 0;
+   
+   virtual long __stdcall GetNames( 
+      /* [string][in] */ const wchar_t * wszQualifierName,
+      /* [in] */ long lFlags,
+      /* [in] */ wchar_variant *pQualifierVal,
+      /* [out] */ void * *pNames) = 0;
+   
+   virtual long __stdcall BeginEnumeration( 
+      /* [in] */ long lEnumFlags) = 0;
+   
+   virtual long __stdcall Next( 
+      /* [in] */ long lFlags,
+      /* [unique][in][out] */ wchar_t * *strName,
+      /* [unique][in][out] */ wchar_variant *pVal,
+      /* [unique][in][out] */ long *pType,
+      /* [unique][in][out] */ long *plFlavor) = 0;
+   
+   virtual long __stdcall EndEnumeration( void) = 0;
+   
+   virtual long __stdcall GetPropertyQualifierSet( 
+      /* [string][in] */ const wchar_t * wszProperty,
+      /* [out] */ void **ppQualSet) = 0;
+   
+   virtual long __stdcall Clone( 
+      /* [out] */ IWbemClassObject_IG **ppCopy) = 0;
+   
+   virtual long __stdcall GetObjectText( 
+      /* [in] */ long lFlags,
+      /* [out] */ wchar_t * *pstrObjectText) = 0;
+   
+   virtual long __stdcall SpawnDerivedClass( 
+      /* [in] */ long lFlags,
+      /* [out] */ IWbemClassObject_IG **ppNewClass) = 0;
+   
+   virtual long __stdcall SpawnInstance( 
+      /* [in] */ long lFlags,
+      /* [out] */ IWbemClassObject_IG **ppNewInstance) = 0;
+   
+   virtual long __stdcall CompareTo( 
+      /* [in] */ long lFlags,
+      /* [in] */ IWbemClassObject_IG *pCompareTo) = 0;
+   
+   virtual long __stdcall GetPropertyOrigin( 
+      /* [string][in] */ const wchar_t * wszName,
+      /* [out] */ wchar_t * *pstrClassName) = 0;
+   
+   virtual long __stdcall InheritsFrom( 
+      /* [in] */ const wchar_t * strAncestor) = 0;
+   
+   virtual long __stdcall GetMethod( 
+      /* [string][in] */ const wchar_t * wszName,
+      /* [in] */ long lFlags,
+      /* [out] */ IWbemClassObject_IG **ppInSignature,
+      /* [out] */ IWbemClassObject_IG **ppOutSignature) = 0;
+   
+   virtual long __stdcall PutMethod( 
+      /* [string][in] */ const wchar_t * wszName,
+      /* [in] */ long lFlags,
+      /* [in] */ IWbemClassObject_IG *pInSignature,
+      /* [in] */ IWbemClassObject_IG *pOutSignature) = 0;
+   
+   virtual long __stdcall DeleteMethod( 
+      /* [string][in] */ const wchar_t * wszName) = 0;
+   
+   virtual long __stdcall BeginMethodEnumeration( 
+      /* [in] */ long lEnumFlags) = 0;
+   
+   virtual long __stdcall NextMethod( 
+      /* [in] */ long lFlags,
+      /* [unique][in][out] */ wchar_t * *pstrName,
+      /* [unique][in][out] */ IWbemClassObject_IG **ppInSignature,
+      /* [unique][in][out] */ IWbemClassObject_IG **ppOutSignature) = 0;
+   
+   virtual long __stdcall EndMethodEnumeration( void) = 0;
+   
+   virtual long __stdcall GetMethodQualifierSet( 
+      /* [string][in] */ const wchar_t * wszMethod,
+      /* [out] */ void **ppQualSet) = 0;
+   
+   virtual long __stdcall GetMethodOrigin( 
+      /* [string][in] */ const wchar_t * wszMethodName,
+      /* [out] */ wchar_t * *pstrClassName) = 0;
+   
+};
+
+
+struct IWbemContext_IG : public IUnknown_IG
+{
+public:
+   virtual long __stdcall Clone( 
+      /* [out] */ IWbemContext_IG **ppNewCopy) = 0;
+   
+   virtual long __stdcall GetNames( 
+      /* [in] */ long lFlags,
+      /* [out] */ void * *pNames) = 0;
+   
+   virtual long __stdcall BeginEnumeration( 
+      /* [in] */ long lFlags) = 0;
+   
+   virtual long __stdcall Next( 
+      /* [in] */ long lFlags,
+      /* [out] */ wchar_t * *pstrName,
+      /* [out] */ wchar_variant *pValue) = 0;
+   
+   virtual long __stdcall EndEnumeration( void) = 0;
+   
+   virtual long __stdcall SetValue( 
+      /* [string][in] */ const wchar_t * wszName,
+      /* [in] */ long lFlags,
+      /* [in] */ wchar_variant *pValue) = 0;
+   
+   virtual long __stdcall GetValue( 
+      /* [string][in] */ const wchar_t * wszName,
+      /* [in] */ long lFlags,
+      /* [out] */ wchar_variant *pValue) = 0;
+   
+   virtual long __stdcall DeleteValue( 
+      /* [string][in] */ const wchar_t * wszName,
+      /* [in] */ long lFlags) = 0;
+   
+   virtual long __stdcall DeleteAll( void) = 0;
+   
+};
+
+
+struct IEnumWbemClassObject_IG : public IUnknown_IG
+{
+public:
+   virtual long __stdcall Reset( void) = 0;
+   
+   virtual long __stdcall Next( 
+      /* [in] */ long lTimeout,
+      /* [in] */ unsigned long uCount,
+      /* [length_is][size_is][out] */ IWbemClassObject_IG **apObjects,
+      /* [out] */ unsigned long *puReturned) = 0;
+   
+   virtual long __stdcall NextAsync( 
+      /* [in] */ unsigned long uCount,
+      /* [in] */ void *pSink) = 0;
+   
+   virtual long __stdcall Clone( 
+      /* [out] */ void **ppEnum) = 0;
+   
+   virtual long __stdcall Skip( 
+      /* [in] */ long lTimeout,
+      /* [in] */ unsigned long nCount) = 0;
+   
+};
+
+struct IWbemServices_IG : public IUnknown_IG
+{
+public:
+   virtual long __stdcall OpenNamespace( 
+      /* [in] */ const wchar_t * strNamespace,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [unique][in][out] */ void **ppWorkingNamespace,
+      /* [unique][in][out] */ void **ppResult) = 0;
+   
+   virtual long __stdcall CancelAsyncCall( 
+      /* [in] */ void *pSink) = 0;
+   
+   virtual long __stdcall QueryObjectSink( 
+      /* [in] */ long lFlags,
+      /* [out] */ void **ppResponseHandler) = 0;
+   
+   virtual long __stdcall GetObject( 
+      /* [in] */ const wchar_t * strObjectPath,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [unique][in][out] */ void **ppObject,
+      /* [unique][in][out] */ void **ppCallResult) = 0;
+   
+   virtual long __stdcall GetObjectAsync( 
+      /* [in] */ const wchar_t * strObjectPath,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [in] */ void *pResponseHandler) = 0;
+   
+   virtual long __stdcall PutClass( 
+      /* [in] */ IWbemClassObject_IG *pObject,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [unique][in][out] */ void **ppCallResult) = 0;
+   
+   virtual long __stdcall PutClassAsync( 
+      /* [in] */ IWbemClassObject_IG *pObject,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [in] */ void *pResponseHandler) = 0;
+   
+   virtual long __stdcall DeleteClass( 
+      /* [in] */ const wchar_t * strClass,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [unique][in][out] */ void **ppCallResult) = 0;
+   
+   virtual long __stdcall DeleteClassAsync( 
+      /* [in] */ const wchar_t * strClass,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [in] */ void *pResponseHandler) = 0;
+   
+   virtual long __stdcall CreateClassEnum( 
+      /* [in] */ const wchar_t * strSuperclass,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [out] */ void **ppEnum) = 0;
+   
+   virtual long __stdcall CreateClassEnumAsync( 
+      /* [in] */ const wchar_t * strSuperclass,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [in] */ void *pResponseHandler) = 0;
+   
+   virtual long __stdcall PutInstance( 
+      /* [in] */ void *pInst,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [unique][in][out] */ void **ppCallResult) = 0;
+   
+   virtual long __stdcall PutInstanceAsync( 
+      /* [in] */ void *pInst,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [in] */ void *pResponseHandler) = 0;
+   
+   virtual long __stdcall DeleteInstance( 
+      /* [in] */ const wchar_t * strObjectPath,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [unique][in][out] */ void **ppCallResult) = 0;
+   
+   virtual long __stdcall DeleteInstanceAsync( 
+      /* [in] */ const wchar_t * strObjectPath,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [in] */ void *pResponseHandler) = 0;
+   
+   virtual long __stdcall CreateInstanceEnum( 
+      /* [in] */ const wchar_t * strFilter,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [out] */ void **ppEnum) = 0;
+   
+   virtual long __stdcall CreateInstanceEnumAsync( 
+      /* [in] */ const wchar_t * strFilter,
+      /* [in] */ long lFlags,
+      /* [in] */ void *pCtx,
+      /* [in] */ void *pResponseHandler) = 0;
+   
+   virtual long __stdcall ExecQuery( 
+      /* [in] */ const wchar_t * strQueryLanguage,
+      /* [in] */ const wchar_t * strQuery,
+      /* [in] */ long lFlags,
+      /* [in] */ IWbemContext_IG *pCtx,
+      /* [out] */ IEnumWbemClassObject_IG **ppEnum) = 0;
+
+   virtual long __stdcall ExecQueryAsync( 
+      /* [in] */ const wchar_t * strQueryLanguage,
+      /* [in] */ const wchar_t * strQuery,
+      /* [in] */ long lFlags,
+      /* [in] */ IWbemContext_IG *pCtx,
+      /* [in] */ void *pResponseHandler) = 0;
+   
+   virtual long __stdcall ExecNotificationQuery( 
+      /* [in] */ const wchar_t * strQueryLanguage,
+      /* [in] */ const wchar_t * strQuery,
+      /* [in] */ long lFlags,
+      /* [in] */ IWbemContext_IG *pCtx,
+      /* [out] */ void **ppEnum) = 0;
+   
+   virtual long __stdcall ExecNotificationQueryAsync( 
+      /* [in] */ const wchar_t * strQueryLanguage,
+      /* [in] */ const wchar_t * strQuery,
+      /* [in] */ long lFlags,
+      /* [in] */ IWbemContext_IG *pCtx,
+      /* [in] */ void *pResponseHandler) = 0;
+   
+   virtual long __stdcall ExecMethod( 
+      /* [in] */ const wchar_t * strObjectPath,
+      /* [in] */ const wchar_t * strMethodName,
+      /* [in] */ long lFlags,
+      /* [in] */ IWbemContext_IG *pCtx,
+      /* [in] */ IWbemClassObject_IG *pInParams,
+      /* [unique][in][out] */ IWbemClassObject_IG **ppOutParams,
+      /* [unique][in][out] */ void **ppCallResult) = 0;
+   
+   virtual long __stdcall ExecMethodAsync( 
+      /* [in] */ const wchar_t * strObjectPath,
+      /* [in] */ const wchar_t * strMethodName,
+      /* [in] */ long lFlags,
+      /* [in] */ IWbemContext_IG *pCtx,
+      /* [in] */ IWbemClassObject_IG *pInParams,
+      /* [in] */ void *pResponseHandler) = 0;
+   
+};
+
+struct IWbemLocator_IG : public IUnknown_IG
+{
+public:
+   virtual long __stdcall ConnectServer( 
+      /* [in] */ const wchar_t * strNetworkResource,
+      /* [in] */ const wchar_t * strUser,
+      /* [in] */ const wchar_t * strPassword,
+      /* [in] */ const wchar_t * strLocale,
+      /* [in] */ long lSecurityFlags,
+      /* [in] */ const wchar_t * strAuthority,
+      /* [in] */ void *pCtx,
+      /* [out] */ IWbemServices_IG **ppNamespace) = 0;
+   
+};
+ 
+
+
 struct interprocess_overlapped 
 {
    unsigned long *internal;
@@ -393,6 +775,10 @@
 //Some windows API declarations
 extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
 extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
+extern "C" __declspec(dllimport) int __stdcall GetProcessTimes
+   ( void *hProcess, interprocess_filetime* lpCreationTime
+   , interprocess_filetime *lpExitTime,interprocess_filetime *lpKernelTime
+   , interprocess_filetime *lpUserTime );
 extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long);
 extern "C" __declspec(dllimport) unsigned long __stdcall GetLastError();
 extern "C" __declspec(dllimport) void * __stdcall GetCurrentProcess();
@@ -423,6 +809,7 @@
 extern "C" __declspec(dllimport) int __stdcall    MoveFileExA (const char *, const char *, unsigned long);
 extern "C" __declspec(dllimport) void __stdcall GetSystemInfo (struct system_info *);
 extern "C" __declspec(dllimport) int __stdcall FlushViewOfFile (void *, std::size_t);
+extern "C" __declspec(dllimport) int __stdcall FlushFileBuffers (void *);
 extern "C" __declspec(dllimport) int __stdcall GetFileSizeEx (void *, __int64 *size);
 extern "C" __declspec(dllimport) unsigned long __stdcall FormatMessageA
    (unsigned long dwFlags,       const void *lpSource,   unsigned long dwMessageId, 
@@ -450,6 +837,26 @@
 extern "C" __declspec(dllimport) void *__stdcall GetFileInformationByHandle(void *, interprocess_by_handle_file_information*);
 
 
+//COM API
+extern "C" __declspec(dllimport) long __stdcall CoInitialize(void *pvReserved);
+extern "C" __declspec(dllimport) long __stdcall CoInitializeSecurity(
+                    void*         pSecDesc,
+                    long                         cAuthSvc,
+                    void *asAuthSvc,
+                    void                        *pReserved1,
+                    unsigned long                        dwAuthnLevel,
+                    unsigned long                        dwImpLevel,
+                    void                        *pAuthList,
+                    unsigned long                        dwCapabilities,
+                    void                        *pReserved3 );
+
+extern "C" __declspec(dllimport) long __stdcall VariantClear(wchar_variant * pvarg);
+extern "C" __declspec(dllimport) long __stdcall CoCreateInstance(const GUID_IG & rclsid, IUnknown_IG *pUnkOuter,
+                    unsigned long dwClsContext, const GUID_IG & riid, void** ppv);
+extern "C" __declspec(dllimport) void __stdcall CoUninitialize(void);
+
+
+
 //API function typedefs
 //Pointer to functions
 typedef long (__stdcall *NtDeleteFile_t)(object_attributes_t *ObjectAttributes); 
@@ -475,10 +882,6 @@
 }  //namespace interprocess  {
 }  //namespace boost  {
 
-#else
-#  include <windows.h>
-#endif   //#if !defined( BOOST_USE_WINDOWS_H )
-
 namespace boost {
 namespace interprocess {
 namespace winapi {
@@ -508,6 +911,12 @@
 inline unsigned long get_current_thread_id()
 {  return GetCurrentThreadId();  }
 
+inline bool get_process_times
+   ( void *hProcess, interprocess_filetime* lpCreationTime
+   , interprocess_filetime *lpExitTime, interprocess_filetime *lpKernelTime
+   , interprocess_filetime *lpUserTime )
+{  return 0 != GetProcessTimes(hProcess, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime); }
+
 inline unsigned long get_current_process_id()
 {  return GetCurrentProcessId();  }
 
@@ -563,20 +972,33 @@
 inline void *open_semaphore(const char *name)
 {  return OpenSemaphoreA(semaphore_all_access, 1, name); }
 
-inline void * create_file_mapping (void * handle, unsigned long access, unsigned long high_size, unsigned long low_size, const char * name)
+class interprocess_all_access_security
 {
    interprocess_security_attributes sa;
    interprocess_security_descriptor sd; 
+   bool initialized;
 
-   if(!InitializeSecurityDescriptor(&sd, security_descriptor_revision))
-      return 0;
-   if(!SetSecurityDescriptorDacl(&sd, true, 0, false))
-      return 0;
-   sa.lpSecurityDescriptor = &sd;
-   sa.nLength = sizeof(interprocess_security_attributes);
-   sa.bInheritHandle = false;
-   return CreateFileMappingA (handle, &sa, access, high_size, low_size, name); 
-  //return CreateFileMappingA (handle, 0, access, high_size, low_size, name);  
+   public:
+   interprocess_all_access_security()
+      : initialized(false)
+   {
+      if(!InitializeSecurityDescriptor(&sd, security_descriptor_revision))
+         return;
+      if(!SetSecurityDescriptorDacl(&sd, true, 0, false))
+         return;
+      sa.lpSecurityDescriptor = &sd;
+      sa.nLength = sizeof(interprocess_security_attributes);
+      sa.bInheritHandle = false;
+      initialized = false;
+   }
+
+   interprocess_security_attributes *get_attributes()
+   {  return &sa; }
+};
+
+inline void * create_file_mapping (void * handle, unsigned long access, unsigned long high_size, unsigned long low_size, const char * name, interprocess_security_attributes *psec)
+{
+   return CreateFileMappingA (handle, psec, access, high_size, low_size, name); 
 }
 
 inline void * open_file_mapping (unsigned long access, const char *name)
@@ -585,12 +1007,12 @@
 inline void *map_view_of_file_ex(void *handle, unsigned long file_access, unsigned long highoffset, unsigned long lowoffset, std::size_t numbytes, void *base_addr)
 {  return MapViewOfFileEx(handle, file_access, highoffset, lowoffset, numbytes, base_addr);  }
 
-inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes = 0)
+inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes, interprocess_security_attributes *psec)
 {
    for (unsigned int attempt(0); attempt < error_sharing_violation_tries; ++attempt){
       void * const handle = CreateFileA(name, access,
                                         file_share_read | file_share_write | file_share_delete,
-                                        0, creation_flags, attributes, 0);
+                                        psec, creation_flags, attributes, 0);
       bool const invalid(invalid_handle_value == handle);
       if (!invalid){
          return handle;
@@ -612,14 +1034,20 @@
 inline void get_system_info(system_info *info)
 {  GetSystemInfo(info); }
 
-inline int flush_view_of_file(void *base_addr, std::size_t numbytes)
-{  return FlushViewOfFile(base_addr, numbytes); }
+inline bool flush_view_of_file(void *base_addr, std::size_t numbytes)
+{  return 0 != FlushViewOfFile(base_addr, numbytes); }
+
+inline bool flush_file_buffers(void *handle)
+{  return 0 != FlushFileBuffers(handle); }
 
 inline bool get_file_size(void *handle, __int64 &size)
 {  return 0 != GetFileSizeEx(handle, &size);  }
 
-inline bool create_directory(const char *name, interprocess_security_attributes* security)
-{  return 0 != CreateDirectoryA(name, security);   }
+inline bool create_directory(const char *name)
+{  
+   interprocess_all_access_security sec;
+   return 0 != CreateDirectoryA(name, sec.get_attributes());   
+}
 
 inline bool remove_directory(const char *lpPathName)
 {  return 0 != RemoveDirectoryA(lpPathName);   }
@@ -728,7 +1156,7 @@
    bool bSuccess = false;
 
    // Create a file mapping object.
-   void * hFileMap = create_file_mapping(hFile, page_readonly, 0, 1, 0);
+   void * hFileMap = create_file_mapping(hFile, page_readonly, 0, 1, 0, 0);
    if(hFileMap)
    {
       // Create a file mapping to get the file name.
@@ -855,7 +1283,7 @@
 
       //First step: Obtain a handle to the file using Win32 rules. This resolves relative paths
       void *fh = create_file(filename, generic_read | delete_access, open_existing,
-         file_flag_backup_semantics | file_flag_delete_on_close); 
+         file_flag_backup_semantics | file_flag_delete_on_close, 0); 
       if(fh == invalid_handle_value){
          return false;
       }
@@ -972,6 +1400,174 @@
    }
 }
 
+
+inline void get_registry_value(const char *folder, const char *value_key, std::vector<unsigned char> &s)
+{
+   s.clear();
+   void *hAdvapi = load_library("Advapi32.dll");
+   if (hAdvapi){
+      library_unloader unloader(hAdvapi);
+      //  Pointer to function RegOpenKeyA
+      RegOpenKeyEx_t pRegOpenKey =
+         (RegOpenKeyEx_t)get_proc_address(hAdvapi, "RegOpenKeyExA");
+      if (pRegOpenKey){
+         //  Pointer to function RegCloseKey
+         RegCloseKey_t pRegCloseKey =
+            (RegCloseKey_t)get_proc_address(hAdvapi, "RegCloseKey");
+         if (pRegCloseKey){
+            //  Pointer to function RegQueryValueA
+            RegQueryValueEx_t pRegQueryValue =
+               (RegQueryValueEx_t)get_proc_address(hAdvapi, "RegQueryValueExA");
+            if (pRegQueryValue){
+               //Open the key
+               void *key;
+               if ((*pRegOpenKey)( hkey_local_machine
+                                 , folder
+                                 , 0
+                                 , key_query_value
+                                 , &key) == 0){
+                  reg_closer key_closer(pRegCloseKey, key);
+
+                  //Obtain the value
+                  unsigned long size;
+                  unsigned long type;
+                  const char *const reg_value = value_key;
+                  long err = (*pRegQueryValue)( key, reg_value, 0, &type, 0, &size);
+                  if(!err){
+                     //Size includes terminating NULL
+                     s.resize(size);
+                     err = (*pRegQueryValue)( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
+                     if(!err)
+                        s.erase(s.end()-1);
+                     (void)err;
+                  }
+               }
+            }
+         }
+      }
+   }
+}
+
+inline bool get_wmi_class_attribute( std::wstring& strValue, const wchar_t *wmi_class, const wchar_t *wmi_class_var)
+{
+	CoInitialize(0);
+ 
+	bool bRet = false;
+ 
+	if( 0 == CoInitializeSecurity( 0, -1, 0, 0, RPC_C_AUTHN_LEVEL_PKT_IG, RPC_C_IMP_LEVEL_IMPERSONATE_IG, 0, EOAC_NONE_IG, 0 ) )
+	{
+		IWbemLocator_IG * pIWbemLocator = 0;
+
+		IWbemServices_IG * pWbemServices = 0;
+		IEnumWbemClassObject_IG * pEnumObject  = 0;
+ 
+		const wchar_t * bstrNamespace = L"root\\cimv2";
+ 
+		if( 0 != CoCreateInstance(
+				CLSID_WbemAdministrativeLocator,
+				0,
+				CLSCTX_INPROC_SERVER_IG | CLSCTX_LOCAL_SERVER_IG,
+				IID_IUnknown,
+				( void ** )&pIWbemLocator
+				)
+			)
+		{
+			return false;
+		}
+ 
+		if( 0 != pIWbemLocator->ConnectServer(
+				bstrNamespace,  // Namespace
+				0,          // Userid
+				0,           // PW
+				0,           // Locale
+				0,              // flags
+				0,           // Authority
+				0,           // Context
+				&pWbemServices
+				)
+			)
+		{
+			pIWbemLocator->Release();
+ 
+			return false;
+		}
+ 
+      strValue.clear();
+      strValue += L"Select ";
+      strValue += wmi_class_var;
+      strValue += L" from ";
+      strValue += wmi_class;
+
+		if ( 0 != pWbemServices->ExecQuery(
+				L"WQL",
+            strValue.c_str(),
+				WBEM_FLAG_RETURN_IMMEDIATELY_IG,
+				0,
+				&pEnumObject
+				)
+			)
+		{
+			pIWbemLocator->Release();
+			pWbemServices->Release();
+ 
+			return false;
+		}
+		
+		unsigned long uCount = 1, uReturned;
+		IWbemClassObject_IG * pClassObject = 0;
+ 
+		if ( 0 != pEnumObject->Reset() )
+		{
+			pIWbemLocator->Release();
+			pWbemServices->Release();
+			pEnumObject->Release();
+ 
+			return false;
+		}
+
+      wchar_variant vwchar;
+
+		while( 0 == pEnumObject->Next( WBEM_INFINITE_IG, uCount, &pClassObject, &uReturned ) )
+		{
+			if ( 0 == pClassObject->Get( L"LastBootUpTime", 0, &vwchar, 0, 0 ) )
+			{
+				bRet = true;
+ 				strValue = vwchar.value.pbstrVal;
+ 				VariantClear(&vwchar );
+ 				break;
+			}
+		}
+ 
+		pIWbemLocator->Release();
+		pWbemServices->Release();
+		pEnumObject->Release();
+		pClassObject->Release();
+	}
+ 
+	CoUninitialize();
+ 
+	return bRet;
+}
+
+inline bool get_last_bootup_time( std::wstring& strValue )
+{
+   bool ret = get_wmi_class_attribute(strValue, L"Win32_OperatingSystem", L"LastBootUpTime");
+   strValue.erase(strValue.find(L'+'));
+   return ret;
+}
+
+inline bool get_last_bootup_time( std::string& str )
+{
+   std::wstring wstr;
+   bool ret = get_last_bootup_time(wstr);
+   str.resize(wstr.size());
+   for(std::size_t i = 0, max = str.size(); i != max; ++i){
+      str[i] = '0' + (wstr[i]-L'0');
+   }
+   return ret;
+}
+
+
 }  //namespace winapi 
 }  //namespace interprocess
 }  //namespace boost 
Modified: trunk/boost/interprocess/detail/workaround.hpp
==============================================================================
--- trunk/boost/interprocess/detail/workaround.hpp	(original)
+++ trunk/boost/interprocess/detail/workaround.hpp	2010-07-25 12:39:26 EDT (Sun, 25 Jul 2010)
@@ -115,7 +115,7 @@
 
 #endif
 
-#if     defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)\
+#if    !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)\
     && !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
 #define BOOST_INTERPROCESS_PERFECT_FORWARDING
 #endif
Modified: trunk/boost/interprocess/detail/xsi_shared_memory_device.hpp
==============================================================================
--- trunk/boost/interprocess/detail/xsi_shared_memory_device.hpp	(original)
+++ trunk/boost/interprocess/detail/xsi_shared_memory_device.hpp	2010-07-25 12:39:26 EDT (Sun, 25 Jul 2010)
@@ -197,9 +197,11 @@
    (mapped_region ®, xsi_named_mutex &mut, std::string &path)
 {
    const char *const filename = "xsi_shm_emulation_file";
+   permissions p;
+   p.set_unrestricted();
    std::string xsi_shm_emulation_file_path;
-   detail::create_tmp_dir_and_get_filename(filename, xsi_shm_emulation_file_path);
-   detail::create_or_open_file(xsi_shm_emulation_file_path.c_str());
+   detail::create_tmp_and_clean_old_and_get_filename(filename, xsi_shm_emulation_file_path);
+   detail::create_or_open_file(xsi_shm_emulation_file_path.c_str(), read_write, p);
    const std::size_t MemSize = sizeof(info_t);
 
    xsi_shared_memory index_shm(open_or_create, xsi_shm_emulation_file_path.c_str(), 1, MemSize, 0666);