Boost logo

Boost-Commit :

From: igaztanaga_at_[hidden]
Date: 2007-10-21 05:01:19


Author: igaztanaga
Date: 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
New Revision: 40267
URL: http://svn.boost.org/trac/boost/changeset/40267

Log:
Doxygen bug workaround. Corrected Solaris errors. Experimental grow/shrink_to_fit for managed_shared_memory and managed_mapped_file.
Added:
   trunk/boost/interprocess/detail/interprocess_tester.hpp (contents, props changed)
Text files modified:
   trunk/boost/interprocess/containers/detail/tree.hpp | 24 +--
   trunk/boost/interprocess/containers/list.hpp | 16 +
   trunk/boost/interprocess/containers/slist.hpp | 19 +
   trunk/boost/interprocess/detail/atomic.hpp | 297 +++++++++++++++------------------------
   trunk/boost/interprocess/detail/file_wrapper.hpp | 9 +
   trunk/boost/interprocess/detail/managed_memory_impl.hpp | 85 ++++++++--
   trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp | 26 ++
   trunk/boost/interprocess/detail/workaround.hpp | 7
   trunk/boost/interprocess/ipc/message_queue.hpp | 10
   trunk/boost/interprocess/managed_mapped_file.hpp | 72 +++-----
   trunk/boost/interprocess/managed_shared_memory.hpp | 32 ++++
   trunk/boost/interprocess/managed_windows_shared_memory.hpp | 7
   trunk/boost/interprocess/mapped_region.hpp | 13 +
   trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp | 115 ++++++++++----
   trunk/boost/interprocess/segment_manager.hpp | 7
   trunk/boost/interprocess/shared_memory_object.hpp | 9
   trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp | 6
   trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp | 2
   trunk/boost/interprocess/sync/named_condition.hpp | 29 ++-
   trunk/boost/interprocess/sync/named_mutex.hpp | 25 ++-
   trunk/boost/interprocess/sync/named_recursive_mutex.hpp | 12 +
   trunk/boost/interprocess/sync/named_semaphore.hpp | 26 ++-
   trunk/boost/interprocess/sync/named_upgradable_mutex.hpp | 12 +
   trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp | 14 +
   24 files changed, 501 insertions(+), 373 deletions(-)

Modified: trunk/boost/interprocess/containers/detail/tree.hpp
==============================================================================
--- trunk/boost/interprocess/containers/detail/tree.hpp (original)
+++ trunk/boost/interprocess/containers/detail/tree.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -671,7 +671,7 @@
    iterator insert_equal(const value_type& v)
    {
       NodePtr p(AllocHolder::create_node(v));
- return iterator(this->icont().insert_equal_upper_bound(*p));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
@@ -679,14 +679,14 @@
    iterator insert_equal(const detail::moved_object<MovableConvertible> &mv)
    {
       NodePtr p(AllocHolder::create_node(mv));
- return iterator(this->icont().insert_equal_upper_bound(*p));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
    }
    #else
    template<class MovableConvertible>
    iterator insert_equal(MovableConvertible &&mv)
    {
       NodePtr p(AllocHolder::create_node(forward<MovableConvertible>(mv)));
- return iterator(this->icont().insert_equal_upper_bound(*p));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
    }
    #endif
 
@@ -715,17 +715,11 @@
    template <class InputIterator>
    void insert_equal(InputIterator first, InputIterator last)
    {
- if(this->empty()){
- //Insert with end hint, to achieve linear
- //complexity if [first, last) is ordered
- iterator end(this->end());
- for( ; first != last; ++first)
- this->insert_equal(end, *first);
- }
- else{
- for( ; first != last; ++first)
- this->insert_equal(*first);
- }
+ //Insert with end hint, to achieve linear
+ //complexity if [first, last) is ordered
+ iterator end(this->end());
+ for( ; first != last; ++first)
+ this->insert_equal(end, *first);
    }
 
    iterator erase(const_iterator position)
@@ -824,7 +818,7 @@
       {}
 
       void operator()(Node &n)
- { this->icont_.insert_equal_upper_bound(n); }
+ { this->icont_.insert_equal(this->icont_.end(), n); }
    };
 
 

Modified: trunk/boost/interprocess/containers/list.hpp
==============================================================================
--- trunk/boost/interprocess/containers/list.hpp (original)
+++ trunk/boost/interprocess/containers/list.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -211,11 +211,12 @@
    public:
    //! Const iterator used to iterate through a list.
    class const_iterator
+ /// @cond
       : public std::iterator<std::bidirectional_iterator_tag,
                                  value_type, list_difference_type,
                                  list_const_pointer, list_const_reference>
    {
- /// @cond
+
       protected:
       typename Icont::iterator m_it;
       explicit const_iterator(typename Icont::iterator it) : m_it(it){}
@@ -225,7 +226,6 @@
       private:
       typename Icont::iterator get()
       { return this->m_it; }
- /// @endcond
 
       public:
       friend class list<T, A>;
@@ -262,13 +262,16 @@
 
       bool operator!= (const const_iterator& r) const
       { return m_it != r.m_it; }
- };
+ }
+ /// @endcond
+ ;
 
    //! Iterator used to iterate through a list
    class iterator
+ /// @cond
       : public const_iterator
    {
- /// @cond
+
       private:
       explicit iterator(typename Icont::iterator it)
          : const_iterator(it)
@@ -276,7 +279,6 @@
    
       typename Icont::iterator get()
       { return this->m_it; }
- /// @endcond
 
       public:
       friend class list<T, A>;
@@ -302,7 +304,9 @@
 
       iterator operator--(int)
          { iterator tmp = *this; --*this; return tmp; }
- };
+ }
+ /// @endcond
+ ;
 
    //! Iterator used to iterate backwards through a list.
    typedef std::reverse_iterator<iterator> reverse_iterator;

Modified: trunk/boost/interprocess/containers/slist.hpp
==============================================================================
--- trunk/boost/interprocess/containers/slist.hpp (original)
+++ trunk/boost/interprocess/containers/slist.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -226,11 +226,12 @@
    public:
    //! Const iterator used to iterate through a list.
    class const_iterator
+ /// @cond
       : public std::iterator<std::forward_iterator_tag,
                                  value_type, list_difference_type,
                                  list_const_pointer, list_const_reference>
    {
- /// @cond
+
       protected:
       typename Icont::iterator m_it;
       explicit const_iterator(typename Icont::iterator it) : m_it(it){}
@@ -239,7 +240,6 @@
       private:
       typename Icont::iterator get()
       { return this->m_it; }
- /// @endcond
 
       public:
       friend class slist<T, A>;
@@ -270,12 +270,16 @@
 
       bool operator!= (const const_iterator& r) const
       { return m_it != r.m_it; }
- };
+ }
+ /// @endcond
+ ;
 
    //! Iterator used to iterate through a list
- class iterator : public const_iterator
- {
+ class iterator
       /// @cond
+ : public const_iterator
+ {
+
       private:
       explicit iterator(typename Icont::iterator it)
          : const_iterator(it)
@@ -283,7 +287,6 @@
    
       typename Icont::iterator get()
       { return this->m_it; }
- /// @endcond
 
       public:
       friend class slist<T, A>;
@@ -303,7 +306,9 @@
 
       iterator operator++(int)
          { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
- };
+ }
+ /// @endcond
+ ;
 
    public:
    //! <b>Effects</b>: Constructs a list taking the allocator as parameter.

Modified: trunk/boost/interprocess/detail/atomic.hpp
==============================================================================
--- trunk/boost/interprocess/detail/atomic.hpp (original)
+++ trunk/boost/interprocess/detail/atomic.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -1,23 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
-//! Copyright 2000-2005 The Apache Software Foundation or its licensors, as
-//! applicable.
-//!
-//! Licensed under the Apache License, Version 2.0 (the "License");
-//! you may not use this file except in compliance with the License.
-//! You may obtain a copy of the License at
-//!
-//! http://www.apache.org/licenses/LICENSE-2.0
-//!
-//! Unless required by applicable law or agreed to in writing, software
-//! distributed under the License is distributed on an "AS IS" BASIS,
-//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//! See the License for the specific language governing permissions and
-//! limitations under the License.
-//////////////////////////////////////////////////////////////////////////////
-//
-// This is a modified file (apr_atomic.c) of Apache APR project
 //
-// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2006-2007. 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)
 //
@@ -36,27 +19,11 @@
 namespace interprocess{
 namespace detail{
 
-//! 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);
-
-//! Atomically subtract 'val' from an apr_uint32_t
-//! "mem": pointer to the object
-//! "val": amount to subtract
-inline void atomic_sub32(volatile boost::uint32_t *mem, boost::uint32_t 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);
 
-//! Atomically decrement an boost::uint32_t by 1
-//! "mem": pointer to the atomic value
-//! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem);
-
 //! Atomically read an boost::uint32_t from memory
 inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem);
 
@@ -74,46 +41,23 @@
 inline boost::uint32_t atomic_cas32
    (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp);
 
-//! Exchange an boost::uint32_t's value with "val".
-//! "mem": pointer to the value
-//! "val": what to swap it with
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint32_t val);
-
-/*
-//! Compare the pointer's value with "cmp".
-//! If they are the same swap the value with "with"
-//! "mem": pointer to the pointer
-//! "with": what to swap it with
-//! "cmp": the value to compare it to
-//! Returns the old value of the pointer
-inline void *atomic_casptr(volatile void **mem, void *with, const void *cmp);
-*/
-
 } //namespace detail{
 } //namespace interprocess{
 } //namespace boost{
 
 #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
 
-# include <boost/interprocess/detail/win32_api.hpp>
+#include <boost/interprocess/detail/win32_api.hpp>
 
 namespace boost{
 namespace interprocess{
 namespace detail{
 
-//! Atomically add 'val' to an boost::uint32_t
-//! "mem": pointer to the object
-//! "val": amount to add
+//! 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_add32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return winapi::interlocked_exchange_add((volatile long*)mem, val); }
-
-//! Atomically subtract 'val' from an apr_uint32_t
-//! "mem": pointer to the object
-//! "val": amount to subtract
-inline void atomic_sub32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ winapi::interlocked_exchange_add((volatile long*)mem, (boost::uint32_t)(-val)); }
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
+{ return winapi::interlocked_decrement((volatile long*)mem) + 1; }
 
 //! Atomically increment an apr_uint32_t by 1
 //! "mem": pointer to the object
@@ -121,12 +65,6 @@
 inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
 { return winapi::interlocked_increment((volatile long*)mem)-1; }
 
-//! Atomically decrement an boost::uint32_t by 1
-//! "mem": pointer to the atomic value
-//! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem)
-{ return winapi::interlocked_decrement((volatile long*)mem) != 0; }
-
 //! Atomically read an boost::uint32_t from memory
 inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
 { return *mem; }
@@ -147,42 +85,42 @@
    (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
 { return winapi::interlocked_compare_exchange((volatile long*)mem, with, cmp); }
 
-//! Exchange an boost::uint32_t's value with "val".
-//! "mem": pointer to the value
-//! "val": what to swap it with
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return winapi::interlocked_exchange((volatile long*)mem, val); }
-/*
-//! Compare the pointer's value with "cmp".
-//! If they are the same swap the value with "with"
-//! "mem": pointer to the pointer
-//! "with": what to swap it with
-//! "cmp": the value to compare it to
-//! Returns the old value of the pointer
-inline void *atomic_casptr(volatile void **mem, void *with, const void *cmp);
-{ return winapi::interlocked_compare_exchange_pointer(mem, with, cmp); }
-*/
 } //namespace detail{
 } //namespace interprocess{
 } //namespace boost{
 
 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
 
-//#include <stdlib.h>
-
 namespace boost {
 namespace interprocess {
 namespace detail{
 
-static boost::uint32_t inline intel_atomic_add32
- (volatile boost::uint32_t *mem, boost::uint32_t val)
+//! 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)
 {
- asm volatile ("lock; xaddl %0,%1"
- : "=r"(val), "=m"(*mem) // outputs
- : "0"(val), "m"(*mem) // inputs
+ boost::uint32_t prev = cmp;
+ asm volatile( "lock\n\t"
+ "cmpxchg %3,%1"
+ : "=a" (prev), "=m" (*(mem))
+ : "0" (prev), "r" (with)
                : "memory", "cc");
- return val;
+ return prev;
+/*
+ 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
@@ -191,77 +129,48 @@
 //! Returns the old value pointed to by mem
 inline boost::uint32_t atomic_add32
    (volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return intel_atomic_add32(mem, val); }
-
-//! Atomically subtract 'val' from an apr_uint32_t
-//! "mem": pointer to the object
-//! "val": amount to subtract
-inline void atomic_sub32(volatile boost::uint32_t *mem, boost::uint32_t val)
 {
- asm volatile ("lock; subl %1, %0"
- :
- : "m" (*(mem)), "r" (val)
- : "memory", "cc");
+ // int r = *pw;
+ // *mem += val;
+ // return r;
+ int r;
+
+ asm volatile
+ (
+ "lock\n\t"
+ "xadd %1, %0":
+ "+m"( *mem ), "=r"( r ): // outputs (%0, %1)
+ "1"( val ): // inputs (%2 == %1)
+ "memory", "cc" // clobbers
+ );
+
+ 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
 //! "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 intel_atomic_add32(mem, 1); }
+{ return atomic_add32(mem, 1); }
 
 //! Atomically decrement an boost::uint32_t by 1
 //! "mem": pointer to the atomic value
-//! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem)
-{
- unsigned char prev;
-
- asm volatile ("lock; decl %1;\n\t"
- "setnz %%al"
- : "=a" (prev)
- : "m" (*(mem))
- : "memory", "cc");
- return prev != 0;
-}
+//! 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)
-{
- boost::uint32_t prev;
-
- asm volatile ("lock; cmpxchgl %1, %2"
- : "=a" (prev)
- : "r" (with), "m" (*(mem)), "0"(cmp)
- : "memory", "cc");
- return prev;
-}
-
-//! Exchange an boost::uint32_t's value with "val".
-//! "mem": pointer to the value
-//! "val": what to swap it with
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{
- boost::uint32_t prev = val;
-
- asm volatile ("lock; xchgl %0, %1"
- : "=r" (prev)
- : "m" (*(mem)), "0"(prev)
- : "memory");
- return prev;
-}
-
 //! Atomically set an boost::uint32_t in memory
 //! "mem": pointer to the object
 //! "param": val value that the object will assume
@@ -310,7 +219,7 @@
    (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
 {
    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?
@@ -327,11 +236,45 @@
    return prev;
 }
 
-//! Atomically subtract 'val' from an apr_uint32_t
+//! 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(-1u)); }
+
+//! Atomically read an boost::uint32_t from memory
+inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
+{ return *mem; }
+
+//! 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 detail{
+} //namespace interprocess{
+} //namespace boost{
+
+#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+
+namespace boost {
+namespace interprocess {
+namespace detail{
+
+//! Atomically add 'val' to an boost::uint32_t
 //! "mem": pointer to the object
-//! "val": amount to subtract
-inline void atomic_sub32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ atomic_add32(mem, boost::uint32_t(-val)); }
+//! "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
@@ -341,32 +284,29 @@
 
 //! Atomically decrement an boost::uint32_t by 1
 //! "mem": pointer to the atomic value
-//! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem)
-{ return 0 != (atomic_add32(mem, boost::uint32_t(-1u)) - 1u); }
+//! 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; }
 
-//! Exchange an boost::uint32_t's value with "val".
+//! Compare an boost::uint32_t's value with "cmp".
+//! If they are the same swap the value with "with"
 //! "mem": pointer to the value
-//! "val": what to swap it with
+//! "with" what to swap it with
+//! "cmp": the value to compare it to
 //! Returns the old value of *mem
-inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{
- boost::uint32_t prev;
- do {
- prev = *mem;
- } while (atomic_cas32(mem, val, prev) != prev);
- return prev;
-}
+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), with, cmp); }
 
 //! 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)
-{ atomic_xchg32(mem, val); }
+{ *mem = val; }
 
 } //namespace detail{
 } //namespace interprocess{
@@ -397,12 +337,6 @@
    (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
 { return atomic_cas_32(reinterpret_cast<volatile ::uint32_t*>(mem), cmp, with); }
 
-//! Atomically subtract 'val' from an apr_uint32_t
-//! "mem": pointer to the object
-//! "val": amount to subtract
-inline void atomic_sub32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return atomic_add_32(reinterpret_cast<volatile ::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
@@ -411,21 +345,14 @@
 
 //! Atomically decrement an boost::uint32_t by 1
 //! "mem": pointer to the atomic value
-//! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem)
-{ return atomic_add_32_nv(reinterpret_cast<volatile ::uint32_t*>(mem), -1) != 0; }
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
+{ return atomic_add_32_nv(reinterpret_cast<volatile ::uint32_t*>(mem), (boost::uint32_t)-1) + 1; }
 
 //! Atomically read an boost::uint32_t from memory
 inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
 { return *mem; }
 
-//! Exchange an boost::uint32_t's value with "val".
-//! "mem": pointer to the value
-//! "val": what to swap it with
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return atomic_swap_32(reinterpret_cast<volatile ::uint32_t*>(mem), val); }
-
 //! Atomically set an boost::uint32_t in memory
 //! "mem": pointer to the object
 //! "param": val value that the object will assume
@@ -454,7 +381,7 @@
 //! Atomically decrement an boost::uint32_t by 1
 //! "mem": pointer to the atomic value
 //! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem)
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
 { return __ATOMIC_DECREMENT_LONG(mem); }
 
 // Rational for the implementation of the atomic read and write functions.
@@ -513,7 +440,7 @@
 } //namespace boost{
 
 #else
-
+
 #error No atomic operations implemented for this platform, sorry!
 
 #endif

Modified: trunk/boost/interprocess/detail/file_wrapper.hpp
==============================================================================
--- trunk/boost/interprocess/detail/file_wrapper.hpp (original)
+++ trunk/boost/interprocess/detail/file_wrapper.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -86,7 +86,7 @@
    //!Returns false on error. Never throws
    static bool remove(const char *name);
    
- //!Sets the size of the fil
+ //!Sets the size of the file
    void truncate(offset_t length);
 
    //!Closes the
@@ -97,6 +97,10 @@
    //!used in the constructor
    const char *get_name() const;
 
+ //!Returns the name of the file
+ //!used in the constructor
+ bool get_size(offset_t &size) const;
+
    //!Returns access mode
    //!used in the constructor
    mode_t get_mode() const;
@@ -126,6 +130,9 @@
 inline const char *file_wrapper::get_name() const
 { return m_filename.c_str(); }
 
+inline bool file_wrapper::get_size(offset_t &size) const
+{ return get_file_size((file_handle_t)m_handle, size); }
+
 inline void file_wrapper::swap(file_wrapper &other)
 {
    std::swap(m_handle, other.m_handle);

Added: trunk/boost/interprocess/detail/interprocess_tester.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/interprocess_tester.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -0,0 +1,31 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007. 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_INTERPROCESS_TESTER_HPP
+#define BOOST_INTERPROCESS_DETAIL_INTERPROCESS_TESTER_HPP
+
+namespace boost{
+namespace interprocess{
+namespace detail{
+
+class interprocess_tester
+{
+ public:
+ template<class T>
+ static void dont_close_on_destruction(T &t)
+ { t.dont_close_on_destruction(); }
+};
+
+} //namespace detail{
+} //namespace interprocess{
+} //namespace boost{
+
+#endif //#ifndef BOOST_INTERPROCESS_DETAIL_INTERPROCESS_TESTER_HPP
+

Modified: trunk/boost/interprocess/detail/managed_memory_impl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_memory_impl.hpp (original)
+++ trunk/boost/interprocess/detail/managed_memory_impl.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -22,6 +22,7 @@
 #include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
 #include <boost/interprocess/sync/mutex_family.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/detail/os_file_functions.hpp>
 #include <boost/interprocess/creation_tags.hpp>
 #include <boost/interprocess/sync/interprocess_mutex.hpp>
 #include <boost/interprocess/exceptions.hpp>
@@ -64,11 +65,11 @@
 //!algorithm to place a named_allocator_algo, who takes care of name mappings.
 //!The class can be customized with the char type used for object names
 //!and the memory allocation algorithm to be used.*/
-template<
- class CharType,
- class MemoryAlgorithm,
- template<class IndexConfig> class IndexType
- >
+template < class CharType
+ , class MemoryAlgorithm
+ , template<class IndexConfig> class IndexType
+ , std::size_t Offset = 0
+ >
 class basic_managed_memory_impl
 {
    //Non-copyable
@@ -103,11 +104,57 @@
 
    private:
    typedef basic_managed_memory_impl
- <CharType, MemoryAlgorithm, IndexType> self_t;
+ <CharType, MemoryAlgorithm, IndexType, Offset> self_t;
    typedef typename
            segment_manager::char_ptr_holder_t char_ptr_holder_t;
 
    protected:
+ template<class ManagedMemory>
+ static bool grow(const char *filename, std::size_t extra_bytes)
+ {
+ typedef typename ManagedMemory::device_type device_type;
+ //Increase file size
+ try{
+ offset_t old_size;
+ {
+ device_type f(open_or_create, filename, read_write);
+ if(!f.get_size(old_size))
+ return false;
+ f.truncate(old_size + extra_bytes);
+ }
+ ManagedMemory managed_memory(open_only, filename);
+ //Grow always works
+ managed_memory.self_t::grow(extra_bytes);
+ }
+ catch(...){
+ return false;
+ }
+ return true;
+ }
+
+ template<class ManagedMemory>
+ static bool shrink_to_fit(const char *filename)
+ {
+ typedef typename ManagedMemory::device_type device_type;
+ std::size_t new_size, old_size;
+ try{
+ ManagedMemory managed_memory(open_only, filename);
+ old_size = managed_memory.get_size();
+ managed_memory.self_t::shrink_to_fit();
+ new_size = managed_memory.get_size();
+ }
+ catch(...){
+ return false;
+ }
+
+ //Decrease file size
+ {
+ device_type f(open_or_create, filename, read_write);
+ f.truncate(new_size);
+ }
+ return true;
+ }
+
    //!Constructor. Allocates basic resources. Never throws.
    basic_managed_memory_impl()
       : mp_header(0){}
@@ -196,14 +243,17 @@
 
       if(!mp_header) return false;
       //Create memory
- return instream.read(detail::char_ptr_cast(mp_header),
- (std::streamsize)size).good();
+ return instream.read(detail::char_ptr_cast(this->get_address()),
+ (std::streamsize)this->get_size).good();
    }
 
    //!
    void grow(std::size_t extra_bytes)
    { mp_header->grow(extra_bytes); }
 
+ void shrink_to_fit()
+ { mp_header->shrink_to_fit(); }
+
    public:
 
    //!Returns segment manager. Never throws.
@@ -212,11 +262,11 @@
 
    //!Returns the base address of the memory in this process. Never throws.
    void * get_address () const
- { return mp_header; }
+ { return (char*)mp_header - Offset; }
 
    //!Returns the size of memory segment. Never throws.
    std::size_t get_size () const
- { return mp_header->get_size(); }
+ { return mp_header->get_size() + Offset; }
 
    //!Returns the number of free bytes of the memory
    //!segment
@@ -241,7 +291,7 @@
    //!Transforms an absolute address into an offset from base address.
    //!The address must belong to the memory segment. Never throws.
    handle_t get_handle_from_address (const void *ptr) const
- {
+ {
       return detail::char_ptr_cast(ptr) -
              detail::char_ptr_cast(this->get_address());
    }
@@ -641,8 +691,8 @@
    //!Never throws.
    bool save_to_ostream (std::ostream &outstream)
    {
- return outstream.write(char_ptr_cast(mp_header),
- (std::streamsize)get_size()).good();
+ return outstream.write(char_ptr_cast(this->get_address()),
+ (std::streamsize)this->get_size()).good();
    }
 
    //!Returns a constant iterator to the index storing the
@@ -696,15 +746,6 @@
    { return mp_header->get_deleter<T>(); }
 
    protected:
- //!Sets the base address of the memory in this process.
- //!This is very low level, so use it only if you know what are
- //!you doing. Never throws.
- void set_base (void *addr)
- {
- assert(addr);
- mp_header = static_cast<segment_manager*>(addr);
- }
-
    //!Swaps the segment manager's managed by this managed memory segment.
    //!NOT thread-safe. Never throws.
    void swap(basic_managed_memory_impl &other)

Modified: trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp (original)
+++ trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -18,12 +18,18 @@
 #include <boost/interprocess/detail/utilities.hpp>
 #include <boost/interprocess/detail/type_traits.hpp>
 #include <boost/interprocess/detail/atomic.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
 #include <boost/interprocess/creation_tags.hpp>
 #include <boost/interprocess/detail/mpl.hpp>
 #include <boost/cstdint.hpp>
 
 namespace boost {
 namespace interprocess {
+
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
 namespace detail {
 
 template<class DeviceAbstraction, bool FileBased = true>
@@ -44,13 +50,11 @@
 
    public:
 
- enum
- {
+ static const std::size_t
       ManagedOpenOrCreateUserOffset =
          detail::ct_rounded_size
             < sizeof(boost::uint32_t)
- , detail::alignment_of<detail::max_align>::value>::value
- };
+ , detail::alignment_of<detail::max_align>::value>::value;
 
    managed_open_or_create_impl(create_only_t,
                  const char *name,
@@ -178,12 +182,18 @@
    ~managed_open_or_create_impl()
    {}
 
- std::size_t get_size() const
+ std::size_t get_user_size() const
    { return m_mapped_region.get_size() - ManagedOpenOrCreateUserOffset; }
 
- void *get_address() const
+ void *get_user_address() const
    { return (char*)m_mapped_region.get_address() + ManagedOpenOrCreateUserOffset; }
 
+ std::size_t get_real_size() const
+ { return m_mapped_region.get_size(); }
+
+ void *get_real_address() const
+ { return (char*)m_mapped_region.get_address(); }
+
    void swap(managed_open_or_create_impl &other)
    {
       this->m_name.swap(other.m_name);
@@ -388,6 +398,10 @@
    }
 
    private:
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction()
+ { detail::interprocess_tester::dont_close_on_destruction(m_mapped_region); }
+
    mapped_region m_mapped_region;
    std::string m_name;
 };

Modified: trunk/boost/interprocess/detail/workaround.hpp
==============================================================================
--- trunk/boost/interprocess/detail/workaround.hpp (original)
+++ trunk/boost/interprocess/detail/workaround.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -26,6 +26,9 @@
 
    #if defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES - 0 > 0)
       #define BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #if defined(__CYGWIN__)
+ #define BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK
+ #endif
    #endif
 
    #if ((defined _V6_ILP32_OFFBIG) &&(_V6_ILP32_OFFBIG - 0 > 0)) ||\
@@ -48,10 +51,6 @@
       #define BOOST_INTERPROCESS_POSIX_TIMEOUTS
    #endif
 
- #if defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES - 0 > 0)
- #define BOOST_INTERPROCESS_POSIX_SEMAPHORES
- #endif
-
 #endif
 
 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)

Modified: trunk/boost/interprocess/ipc/message_queue.hpp
==============================================================================
--- trunk/boost/interprocess/ipc/message_queue.hpp (original)
+++ trunk/boost/interprocess/ipc/message_queue.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -433,7 +433,7 @@
                                 const void *buffer, std::size_t buffer_size,
                                 unsigned int priority, const boost::posix_time::ptime &abs_time)
 {
- detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_address());
+ detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_user_address());
    //Check if buffer is smaller than maximum allowed
    if (buffer_size > p_hdr->m_max_msg_size) {
       throw interprocess_exception(size_error);
@@ -517,7 +517,7 @@
                           std::size_t &recvd_size, unsigned int &priority,
                           const boost::posix_time::ptime &abs_time)
 {
- detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_address());
+ detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_user_address());
    //Check if buffer is big enough for any message
    if (buffer_size < p_hdr->m_max_msg_size) {
       throw interprocess_exception(size_error);
@@ -586,18 +586,18 @@
 
 inline std::size_t message_queue::get_max_msg() const
 {
- detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_address());
+ detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_user_address());
    return p_hdr ? p_hdr->m_max_num_msg : 0; }
 
 inline std::size_t message_queue::get_max_msg_size() const
 {
- detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_address());
+ detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_user_address());
    return p_hdr ? p_hdr->m_max_msg_size : 0;
 }
 
 inline std::size_t message_queue::get_num_msg()
 {
- detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_address());
+ detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_user_address());
    if(p_hdr){
       //---------------------------------------------
       scoped_lock<interprocess_mutex> lock(p_hdr->m_mutex);

Modified: trunk/boost/interprocess/managed_mapped_file.hpp
==============================================================================
--- trunk/boost/interprocess/managed_mapped_file.hpp (original)
+++ trunk/boost/interprocess/managed_mapped_file.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -40,14 +40,20 @@
>
 class basic_managed_mapped_file
    : public detail::basic_managed_memory_impl
- <CharType, AllocationAlgorithm, IndexType>
+ <CharType, AllocationAlgorithm, IndexType
+ ,detail::managed_open_or_create_impl<detail::file_wrapper>::ManagedOpenOrCreateUserOffset>
 {
    /// @cond
+ public:
+ typedef detail::basic_managed_memory_impl
+ <CharType, AllocationAlgorithm, IndexType,
+ detail::managed_open_or_create_impl<detail::file_wrapper>::ManagedOpenOrCreateUserOffset> base_t;
+ typedef detail::file_wrapper device_type;
+
    private:
 
- typedef detail::basic_managed_memory_impl
- <CharType, AllocationAlgorithm, IndexType> base_t;
    typedef detail::create_open_func<base_t> create_open_func_t;
+ typedef detail::managed_open_or_create_impl<detail::file_wrapper> managed_open_or_create_type;
 
    basic_managed_mapped_file *get_this_pointer()
    { return this; }
@@ -130,50 +136,28 @@
 
    //!Tries to resize mapped file so that we have room for
    //!more objects.
- //!WARNING: The memory mapping can change. To be able to use
- //!this function, all pointers constructed in this buffer
- //!must be offset pointers. Otherwise, the result is undefined.
- //!Returns true if the growth has been successful, so you will
- //!have some extra bytes to allocate new objects. If returns
- //!false, the heap allocation has failed.
-/*
- bool grow(std::size_t extra_bytes)
- {
- //If memory is reallocated, data will
- //be automatically copied
- std::size_t old_size = m_mfile.get_size();
- std::size_t new_size = old_size + extra_bytes;
- m_mfile.close();
- //Increase file size
- {
- std::ofstream file(m_filename.c_str(),
- std::ios::binary |std::ios::in | std::ios::out);
- if(!file){
- return false;
- }
- if(!file.seekp(static_cast<std::streamoff>(new_size - 1))){
- return false;
- }
- if(!file.write("", 1)){
- return false;
- }
- }
-
- if(!m_mfile.open(m_filename.c_str(), 0, new_size,
- (file_mapping::mode_t)read_write)){
- return false;
- }
-
- //Grow always works
- base_t::close_impl();
- base_t::open_impl(m_mfile.get_address(), new_size);
- base_t::grow(extra_bytes);
- return true;
+ //!
+ //!This function is not synchronized so no other thread or process should
+ //!be reading or writing the file
+ static bool grow(const char *filename, std::size_t extra_bytes)
+ {
+ return base_t::template grow
+ <basic_managed_mapped_file>(filename, extra_bytes);
    }
-*/
+
+ //!Tries to resize mapped file to minimized the size of the file.
+ //!
+ //!This function is not synchronized so no other thread or process should
+ //!be reading or writing the file
+ static bool shrink_to_fit(const char *filename)
+ {
+ return base_t::template shrink_to_fit
+ <basic_managed_mapped_file>(filename);
+ }
+
    /// @cond
    private:
- detail::managed_open_or_create_impl<detail::file_wrapper> m_mfile;
+ managed_open_or_create_type m_mfile;
    /// @endcond
 };
 

Modified: trunk/boost/interprocess/managed_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_shared_memory.hpp (original)
+++ trunk/boost/interprocess/managed_shared_memory.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -40,12 +40,19 @@
          template<class IndexConfig> class IndexType
>
 class basic_managed_shared_memory
- : public detail::basic_managed_memory_impl <CharType, AllocationAlgorithm, IndexType>
+ : public detail::basic_managed_memory_impl
+ <CharType, AllocationAlgorithm, IndexType
+ ,detail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset>
    , private detail::managed_open_or_create_impl<shared_memory_object>
 {
    /// @cond
+ public:
+ typedef shared_memory_object device_type;
+
+ private:
    typedef detail::basic_managed_memory_impl
- <CharType, AllocationAlgorithm, IndexType> base_t;
+ <CharType, AllocationAlgorithm, IndexType,
+ detail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset> base_t;
    typedef detail::managed_open_or_create_impl
       <shared_memory_object> base2_t;
 
@@ -129,6 +136,27 @@
       base_t::swap(other);
       base2_t::swap(other);
    }
+
+ //!Tries to resize the managed shared memory object so that we have
+ //!room for more objects.
+ //!
+ //!This function is not synchronized so no other thread or process should
+ //!be reading or writing the file
+ static bool grow(const char *filename, std::size_t extra_bytes)
+ {
+ return base_t::template grow
+ <basic_managed_shared_memory>(filename, extra_bytes);
+ }
+
+ //!Tries to resize the managed shared memory to minimized the size of the file.
+ //!
+ //!This function is not synchronized so no other thread or process should
+ //!be reading or writing the file
+ static bool shrink_to_fit(const char *filename)
+ {
+ return base_t::template shrink_to_fit
+ <basic_managed_shared_memory>(filename);
+ }
 };
 
 } //namespace interprocess {

Modified: trunk/boost/interprocess/managed_windows_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_windows_shared_memory.hpp (original)
+++ trunk/boost/interprocess/managed_windows_shared_memory.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -48,13 +48,14 @@
>
 class basic_managed_windows_shared_memory
    : public detail::basic_managed_memory_impl
- <CharType, AllocationAlgorithm, IndexType>
+ <CharType, AllocationAlgorithm, IndexType
+ ,detail::managed_open_or_create_impl<windows_shared_memory>::ManagedOpenOrCreateUserOffset>
 {
    /// @cond
    private:
    typedef detail::basic_managed_memory_impl
- <CharType, AllocationAlgorithm, IndexType> base_t;
-
+ <CharType, AllocationAlgorithm, IndexType,
+ detail::managed_open_or_create_impl<windows_shared_memory>::ManagedOpenOrCreateUserOffset> base_t;
    typedef detail::create_open_func<base_t> create_open_func_t;
 
    basic_managed_windows_shared_memory *get_this_pointer()

Modified: trunk/boost/interprocess/mapped_region.hpp
==============================================================================
--- trunk/boost/interprocess/mapped_region.hpp (original)
+++ trunk/boost/interprocess/mapped_region.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -42,6 +42,10 @@
 namespace boost {
 namespace interprocess {
 
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
 //!The mapped_region class represents a portion or region created from a
 //!memory_mappable object.
 class mapped_region
@@ -133,6 +137,9 @@
    #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
    file_handle_t m_file_mapping_hnd;
    #endif
+
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
    /// @endcond
 };
 
@@ -356,6 +363,9 @@
    #endif
 }
 
+inline void mapped_region::dont_close_on_destruction()
+{}
+
 #else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
 
 inline mapped_region::mapped_region()
@@ -503,6 +513,9 @@
    }
 }
 
+inline void mapped_region::dont_close_on_destruction()
+{ m_base = MAP_FAILED; }
+
 #endif //##if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
 
 template<int dummy>

Modified: trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp (original)
+++ trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -29,7 +29,6 @@
 #include <boost/interprocess/detail/math_functions.hpp>
 #include <boost/interprocess/detail/type_traits.hpp>
 #include <boost/interprocess/sync/scoped_lock.hpp>
-#include <boost/intrusive/set.hpp>
 #include <boost/assert.hpp>
 #include <boost/static_assert.hpp>
 #include <algorithm>
@@ -40,6 +39,14 @@
 #include <assert.h>
 #include <new>
 
+//#define BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
+
+#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
+#include <boost/intrusive/set.hpp>
+#else
+#include <boost/intrusive/splay_set.hpp>
+#endif
+
 //!\file
 //!Describes a best-fit algorithm based in an intrusive red-black tree used to allocate
 //!objects in shared memory. This class is intended as a base class for single segment
@@ -77,9 +84,13 @@
    typedef typename detail::
       pointer_to_other<void_pointer, char>::type char_ptr;
 
+#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
    typedef typename bi::make_set_base_hook
+#else
+ typedef typename bi::make_splay_set_base_hook
+#endif
       < bi::void_pointer<VoidPointer>
- , bi::link_mode<bi::normal_link> >::type TreeHook;
+ , bi::link_mode<bi::normal_link> >::type TreeHook;
 
    typedef detail::multi_allocation_next<void_pointer> multi_allocation_next_t;
    typedef typename multi_allocation_next_t::
@@ -119,8 +130,13 @@
 
    //!Shared interprocess_mutex to protect memory allocate/deallocate
    typedef typename MutexFamily::mutex_type interprocess_mutex;
+#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
    typedef typename bi::make_multiset
+#else
+ typedef typename bi::make_splay_multiset
+#endif
       <block_ctrl, bi::base_hook<TreeHook> >::type Imultiset;
+
    typedef typename Imultiset::iterator imultiset_iterator;
 
    //!This struct includes needed data and derives from
@@ -186,13 +202,18 @@
    //!This function is normally used for security reasons.
    void zero_free_memory();
 
- //!Increases managed memory in extra_size bytes more
+ //!Increases managed memory in
+ //!extra_size bytes more
    void grow(std::size_t extra_size);
 
+ //!Decreases managed memory as much as possible
+ void shrink_to_fit();
+
    //!Returns true if all allocated memory has been deallocated
    bool all_memory_deallocated();
 
- //!Makes an internal sanity check and returns true if success
+ //!Makes an internal sanity check
+ //!and returns true if success
    bool check_sanity();
 
    template<class T>
@@ -380,6 +401,57 @@
 }
 
 template<class MutexFamily, class VoidPointer>
+void rbtree_best_fit<MutexFamily, VoidPointer>::shrink_to_fit()
+{
+ //Get the address of the first block
+ std::size_t block1_off =
+ algo_impl_t::multiple_of_units(sizeof(*this) + m_header.m_extra_hdr_bytes);
+
+ block_ctrl *first_block = reinterpret_cast<block_ctrl *>
+ (detail::char_ptr_cast(this) + block1_off);
+ block_ctrl *old_end_block = priv_prev_block(first_block);
+ assert(priv_is_allocated_block(old_end_block));
+ assert(old_end_block->m_end);
+ std::size_t old_end_block_size = old_end_block->m_size;
+
+ block_ctrl *last_block = priv_prev_block(old_end_block);
+
+ void *unique_block = 0;
+ if(last_block == first_block){
+ std::size_t ignore;
+ unique_block = priv_allocate(allocate_new, 0, 0, ignore).first;
+ if(!unique_block)
+ return;
+ last_block = priv_prev_block(old_end_block);
+ }
+
+ //The last block must be free to be able to shrink
+ if(priv_is_allocated_block(last_block))
+ return;
+
+ std::size_t last_block_size = last_block->m_size;
+
+ //Update managed buffer's size
+ m_header.m_size -= last_block->m_size*Alignment;
+
+ //Erase block from the free tree, since we will erase it
+ m_header.m_imultiset.erase(Imultiset::s_iterator_to(*last_block));
+
+ std::size_t shrunk_border_offset = (detail::char_ptr_cast(last_block) -
+ detail::char_ptr_cast(this)) + EndCtrlBlockBytes;
+
+ block_ctrl *new_end_block = last_block;
+ priv_mark_as_allocated_block(new_end_block);
+ new_end_block->m_end = 1;
+ new_end_block->m_size = old_end_block_size + last_block_size;
+ priv_tail_size(new_end_block, new_end_block->m_size);
+ assert(priv_prev_block(first_block) == new_end_block);
+ assert(shrunk_border_offset == m_header.m_size);
+ if(unique_block)
+ priv_deallocate(unique_block);
+}
+
+template<class MutexFamily, class VoidPointer>
 void rbtree_best_fit<MutexFamily, VoidPointer>::
    priv_add_segment(void *addr, std::size_t size)
 {
@@ -419,7 +491,6 @@
 
    //Check that the alignment is power of two (we use some optimizations based on this)
    //assert((Alignment % 2) == 0);
-
    //Insert it in the intrusive containers
    m_header.m_imultiset.insert(*first_big_block);
 }
@@ -507,7 +578,8 @@
    boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
    //-----------------------
    std::size_t ignore;
- return priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
+ void * ret = priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
+ return ret;
 }
 
 template<class MutexFamily, class VoidPointer>
@@ -984,38 +1056,7 @@
 {
    std::size_t upper_nunits = nunits + BlockCtrlUnits;
    imultiset_iterator it_old = Imultiset::s_iterator_to(*block);
-/*
- if (block->m_size >= upper_nunits){
- //Now we have to update the data in the tree
- m_header.m_imultiset.erase(ittree);
 
- //This block is bigger than needed, split it in
- //two blocks, the first's size will be "units" and
- //the second's size "block->m_size-units"
- std::size_t block_old_size = block->m_size;
- block->m_size = nunits;
- assert(block->m_size >= BlockCtrlUnits);
- priv_tail_size(block, block->m_size);
-
- //This is the remaining block
- block_ctrl *new_block = new(reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(block) + Alignment*nunits))block_ctrl;
- new_block->m_size = block_old_size - nunits;
- assert(new_block->m_size >= BlockCtrlUnits);
- priv_tail_size(new_block, new_block->m_size);
- priv_mark_as_free_block(new_block);
-
- //Insert the new block in the container
- m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *new_block);
- }
- else if (block->m_size >= nunits){
- m_header.m_imultiset.erase(ittree);
- }
- else{
- assert(0);
- return 0;
- }
-*/
    if (block->m_size >= upper_nunits){
       //This block is bigger than needed, split it in
       //two blocks, the first's size will be "units" and

Modified: trunk/boost/interprocess/segment_manager.hpp
==============================================================================
--- trunk/boost/interprocess/segment_manager.hpp (original)
+++ trunk/boost/interprocess/segment_manager.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -195,10 +195,15 @@
    { MemoryAlgorithm::deallocate(addr); }
 
    //!Increases managed memory in extra_size bytes more. This only works
- //!with single-segment management*
+ //!with single-segment management.
    void grow(std::size_t extra_size)
    { MemoryAlgorithm::grow(extra_size); }
 
+ //!Decreases managed memory to the minimum. This only works
+ //!with single-segment management.
+ void shrink_to_fit()
+ { MemoryAlgorithm::shrink_to_fit(); }
+
    //!Returns the result of "all_memory_deallocated()" function
    //!of the used memory algorithm
    bool all_memory_deallocated()

Modified: trunk/boost/interprocess/shared_memory_object.hpp
==============================================================================
--- trunk/boost/interprocess/shared_memory_object.hpp (original)
+++ trunk/boost/interprocess/shared_memory_object.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -20,8 +20,6 @@
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/detail/os_file_functions.hpp>
 #include <cstddef>
-
-
 #include <string>
 
 #ifdef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
@@ -124,6 +122,10 @@
    //!Returns the name of the file.
    const char *get_name() const;
 
+ //!Returns the name of the file
+ //!used in the constructor
+ bool get_size(offset_t &size) const;
+
    //!Returns access mode
    mode_t get_mode() const;
 
@@ -156,6 +158,9 @@
 inline const char *shared_memory_object::get_name() const
 { return m_filename.c_str(); }
 
+inline bool shared_memory_object::get_size(offset_t &size) const
+{ return detail::get_file_size((file_handle_t)m_handle, size); }
+
 inline void shared_memory_object::swap(shared_memory_object &other)
 {
    std::swap(m_handle, other.m_handle);

Modified: trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -68,14 +68,14 @@
         }
     }
 
- bool ref_release() // nothrow
- { return !detail::atomic_dec32( &use_count_ ); }
+ bool ref_release() // nothrow
+ { return 1 == detail::atomic_dec32( &use_count_ ); }
 
    void weak_add_ref() // nothrow
    { detail::atomic_inc32( &weak_count_ ); }
 
    bool weak_release() // nothrow
- { return !detail::atomic_dec32( &weak_count_ ); }
+ { return 1 == detail::atomic_dec32( &weak_count_ ); }
 
    long use_count() const // nothrow
    { return (long)static_cast<boost::uint32_t const volatile &>( use_count_ ); }

Modified: trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp (original)
+++ trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -167,7 +167,7 @@
          else{
             //If it is a NOTIFY_ALL command, all threads should return
             //from do_timed_wait function. Decrement wait count.
- unlock_enter_mut = !detail::atomic_dec32((boost::uint32_t*)&m_num_waiters);
+ unlock_enter_mut = 1 == detail::atomic_dec32((boost::uint32_t*)&m_num_waiters);
             //Check if this is the last thread of notify_all waiters
             //Only the last thread will release the interprocess_mutex
             if(unlock_enter_mut){

Modified: trunk/boost/interprocess/sync/named_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_condition.hpp (original)
+++ trunk/boost/interprocess/sync/named_condition.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -24,7 +24,7 @@
 #include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 #include <boost/interprocess/sync/emulation/named_creation_functor.hpp>
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#if defined BOOST_INTERPROCESS_POSIX_SEMAPHORES && defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
 #include <boost/interprocess/sync/interprocess_mutex.hpp>
 #include <boost/interprocess/sync/scoped_lock.hpp>
 #endif
@@ -34,9 +34,12 @@
 //!Describes process-shared variables interprocess_condition class
 
 namespace boost {
-
 namespace interprocess {
 
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
 class named_condition
 {
    /// @cond
@@ -116,17 +119,17 @@
       interprocess_condition cond_;
       //If named_mutex is implemented using semaphores
       //we need to store an additional mutex
- #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #if defined BOOST_INTERPROCESS_POSIX_SEMAPHORES && defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
       interprocess_mutex mutex_;
       #endif
    };
 
    interprocess_condition *condition() const
- { return &static_cast<condition_holder*>(m_shmem.get_address())->cond_; }
+ { return &static_cast<condition_holder*>(m_shmem.get_user_address())->cond_; }
 
- #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #if defined BOOST_INTERPROCESS_POSIX_SEMAPHORES && defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
    interprocess_mutex *mutex() const
- { return &static_cast<condition_holder*>(m_shmem.get_address())->mutex_; }
+ { return &static_cast<condition_holder*>(m_shmem.get_user_address())->mutex_; }
 
    template <class Lock>
    void do_wait(Lock& lock)
@@ -146,7 +149,10 @@
       lock.lock();
       return r;
    }
- #endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #endif
+
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
 
    detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
 
@@ -188,7 +194,10 @@
                ,construct_func_t(detail::DoOpen))
 {}
 
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+inline void named_condition::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+
+#if defined BOOST_INTERPROCESS_POSIX_SEMAPHORES && defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
 
 inline void named_condition::notify_one()
 {
@@ -243,7 +252,7 @@
    return true;
 }
 
-#else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#else
 
 inline void named_condition::notify_one()
 { this->condition()->notify_one(); }
@@ -293,7 +302,7 @@
    return true;
 }
 
-#endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#endif
 
 inline bool named_condition::remove(const char *name)
 { return shared_memory_object::remove(name); }

Modified: trunk/boost/interprocess/sync/named_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/named_mutex.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -20,8 +20,9 @@
 #include <boost/interprocess/creation_tags.hpp>
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/sync/emulation/named_creation_functor.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
 
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
    #include <boost/interprocess/sync/posix/semaphore_wrapper.hpp>
 #else
    #include <boost/interprocess/shared_memory_object.hpp>
@@ -34,7 +35,6 @@
 //!Describes a named mutex class for inter-process synchronization
 
 namespace boost {
-
 namespace interprocess {
 
 class named_condition;
@@ -103,11 +103,14 @@
 
    /// @cond
    private:
- #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
+
+ #if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
    detail::named_semaphore_wrapper m_sem;
- #else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #else
    interprocess_mutex *mutex() const
- { return static_cast<interprocess_mutex*>(m_shmem.get_address()); }
+ { return static_cast<interprocess_mutex*>(m_shmem.get_user_address()); }
 
    detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
    typedef detail::named_creation_functor<interprocess_mutex> construct_func_t;
@@ -117,7 +120,7 @@
 
 /// @cond
 
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
 
 inline named_mutex::named_mutex(create_only_t, const char *name)
    : m_sem(detail::DoCreate, name, read_write, 1)
@@ -131,6 +134,9 @@
    : m_sem(detail::DoOpen, name, read_write, 1)
 {}
 
+inline void named_mutex::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_sem); }
+
 inline named_mutex::~named_mutex()
 {}
 
@@ -149,7 +155,10 @@
 inline bool named_mutex::remove(const char *name)
 { return detail::named_semaphore_wrapper::remove(name); }
 
-#else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#else
+
+inline void named_mutex::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
 
 inline named_mutex::~named_mutex()
 {}
@@ -199,7 +208,7 @@
 inline bool named_mutex::remove(const char *name)
 { return shared_memory_object::remove(name); }
 
-#endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#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 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -31,6 +31,10 @@
 namespace boost {
 namespace interprocess {
 
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
 //!A recursive mutex with a global name, so it can be found from different
 //!processes. This mutex can't be placed in shared memory, and
 //!each process should have it's own named_recursive_mutex.
@@ -93,8 +97,11 @@
 
    /// @cond
    private:
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
+
    interprocess_recursive_mutex *mutex() const
- { return static_cast<interprocess_recursive_mutex*>(m_shmem.get_address()); }
+ { return static_cast<interprocess_recursive_mutex*>(m_shmem.get_user_address()); }
 
    detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
    typedef detail::named_creation_functor<interprocess_recursive_mutex> construct_func_t;
@@ -104,6 +111,9 @@
 inline named_recursive_mutex::~named_recursive_mutex()
 {}
 
+inline void named_recursive_mutex::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+
 inline named_recursive_mutex::named_recursive_mutex(create_only_t, const char *name)
    : m_shmem (create_only
                ,name

Modified: trunk/boost/interprocess/sync/named_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_semaphore.hpp (original)
+++ trunk/boost/interprocess/sync/named_semaphore.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -1,4 +1,4 @@
-//////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
@@ -19,9 +19,10 @@
 #include <boost/interprocess/detail/workaround.hpp>
 #include <boost/interprocess/creation_tags.hpp>
 #include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
 #include <boost/interprocess/sync/posix/semaphore_wrapper.hpp>
 #else
 #include <boost/interprocess/shared_memory_object.hpp>
@@ -103,11 +104,14 @@
 
    /// @cond
    private:
- #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
+
+ #if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
    detail::named_semaphore_wrapper m_sem;
- #else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #else
    interprocess_semaphore *semaphore() const
- { return static_cast<interprocess_semaphore*>(m_shmem.get_address()); }
+ { return static_cast<interprocess_semaphore*>(m_shmem.get_user_address()); }
 
    detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
    typedef detail::named_creation_functor<interprocess_semaphore, int> construct_func_t;
@@ -117,7 +121,7 @@
 
 /// @cond
 
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
 
 inline named_semaphore::named_semaphore
    (create_only_t, const char *name, int initialCount)
@@ -137,6 +141,9 @@
 inline named_semaphore::~named_semaphore()
 {}
 
+inline void named_semaphore::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_sem); }
+
 inline void named_semaphore::wait()
 { m_sem.wait(); }
 
@@ -152,11 +159,14 @@
 inline bool named_semaphore::remove(const char *name)
 { return detail::named_semaphore_wrapper::remove(name); }
 
-#else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#else
 
 inline named_semaphore::~named_semaphore()
 {}
 
+inline void named_semaphore::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+
 inline named_semaphore::named_semaphore
    (create_only_t, const char *name, int initialCount)
    : m_shmem (create_only
@@ -205,7 +215,7 @@
 inline bool named_semaphore::remove(const char *name)
 { return shared_memory_object::remove(name); }
 
-#endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#endif
 
 /// @endcond
 

Modified: trunk/boost/interprocess/sync/named_upgradable_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_upgradable_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/named_upgradable_mutex.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -31,6 +31,10 @@
 namespace boost {
 namespace interprocess {
 
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
 class named_condition;
 
 //!A upgradable mutex with a global name, so it can be found from different
@@ -218,8 +222,11 @@
 
    /// @cond
    private:
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
+
    interprocess_upgradable_mutex *mutex() const
- { return static_cast<interprocess_upgradable_mutex*>(m_shmem.get_address()); }
+ { return static_cast<interprocess_upgradable_mutex*>(m_shmem.get_user_address()); }
 
    detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
    typedef detail::named_creation_functor<interprocess_upgradable_mutex> construct_func_t;
@@ -262,6 +269,9 @@
                ,construct_func_t(detail::DoOpen))
 {}
 
+inline void named_upgradable_mutex::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+
 inline void named_upgradable_mutex::lock()
 { this->mutex()->lock(); }
 

Modified: trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp
==============================================================================
--- trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp (original)
+++ trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -26,6 +26,11 @@
 
 namespace boost {
 namespace interprocess {
+
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
 namespace detail {
 
 inline bool semaphore_open
@@ -206,7 +211,10 @@
    { semaphore_open(mp_sem, type, name, mode, count); }
 
    ~named_semaphore_wrapper()
- { semaphore_close(mp_sem); }
+ {
+ if(mp_sem != SEM_FAILED)
+ semaphore_close(mp_sem);
+ }
 
    void post()
    { semaphore_post(mp_sem); }
@@ -224,6 +232,10 @@
    { return semaphore_unlink(name); }
 
    private:
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction()
+ { mp_sem = SEM_FAILED; }
+
    sem_t *mp_sem;
 };
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk