$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: igaztanaga_at_[hidden]
Date: 2007-10-25 02:33:51
Author: igaztanaga
Date: 2007-10-25 02:33:50 EDT (Thu, 25 Oct 2007)
New Revision: 40453
URL: http://svn.boost.org/trac/boost/changeset/40453
Log:
Fixed Solaris and Linux bugs
Text files modified: 
   trunk/boost/interprocess/allocators/allocator.hpp            |     4 +-                                      
   trunk/boost/interprocess/containers/detail/tree.hpp          |    10 +++++-                                  
   trunk/boost/interprocess/detail/managed_memory_impl.hpp      |    58 ----------------------------------------
   trunk/boost/interprocess/indexes/iset_index.hpp              |     4 ++                                      
   trunk/boost/interprocess/indexes/iunordered_set_index.hpp    |     3 +                                       
   trunk/boost/interprocess/managed_heap_memory.hpp             |    31 ---------------------                   
   trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp |    16 +++-------                              
   trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp        |     1                                         
   trunk/boost/interprocess/offset_ptr.hpp                      |    10 ++++--                                  
   trunk/boost/interprocess/sync/named_condition.hpp            |    31 +++++++++++++++------                   
   10 files changed, 50 insertions(+), 118 deletions(-)
Modified: trunk/boost/interprocess/allocators/allocator.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/allocator.hpp	(original)
+++ trunk/boost/interprocess/allocators/allocator.hpp	2007-10-25 02:33:50 EDT (Thu, 25 Oct 2007)
@@ -54,8 +54,8 @@
    struct cast_functor
    {
       typedef typename detail::add_reference<T>::type result_type;
-      result_type operator()(char *ptr) const
-      {  return *static_cast<T*>(static_cast<void*>(ptr));  }
+      result_type operator()(char &ptr) const
+      {  return *static_cast<T*>(static_cast<void*>(&ptr));  }
    };
 
    //Self type
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-25 02:33:50 EDT (Thu, 25 Oct 2007)
@@ -87,10 +87,16 @@
 template <class T, class VoidPointer>
 struct rbtree_node
    :  public bi::make_set_base_hook
-         <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type
+         < bi::void_pointer<VoidPointer>
+         , bi::link_mode<bi::normal_link>
+         , bi::optimize_size<true>
+         >::type
 {
    typedef typename bi::make_set_base_hook
-      <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type   hook_type;
+      < bi::void_pointer<VoidPointer>
+      , bi::link_mode<bi::normal_link>
+      , bi::optimize_size<true>
+      >::type   hook_type;
 
    typedef T value_type;
 
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-25 02:33:50 EDT (Thu, 25 Oct 2007)
@@ -211,42 +211,6 @@
          return true;
    }
 
-   //!Creates named_xxx_object from file. Never throws.
-   template<class MemCreatorFunc, class CharT> 
-   bool create_from_file (const CharT *filename, 
-                          MemCreatorFunc &memcreator)
-   {
-      std::basic_ifstream< CharT, std::char_traits<CharT> > 
-         file(filename, std::ios::binary);
-      //Check file
-      if(!file)   return false;
-      //Calculate size
-      file.seekg(0, std::ios::end);
-      std::size_t size = file.tellg();
-      file.seekg(0, std::ios::beg);
-      //Create from stream
-      return create_from_istream(file, size, memcreator);
-   }
-
-   //!Creates memory from an istream. Never throws.
-   template<class MemCreatorFunc> 
-   bool create_from_istream (std::istream &instream, 
-                             std::size_t size,
-                             MemCreatorFunc &memcreator)
-   {
-      if(mp_header)  return false;
-      //Check for minimum size
-      if(size < MemoryAlgorithm::get_min_size (0))
-         return false;
-      
-      mp_header = static_cast<segment_manager*>(memcreator(size));
-
-      if(!mp_header) return false;
-      //Create memory    
-      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); }
@@ -673,28 +637,6 @@
    std::size_t get_num_unique_objects()
    {  return mp_header->get_num_unique_objects();  }
 
-   //!Saves the managed segment memory to a file.
-   //!It's NOT thread-safe. Returns true if successful.
-   //!Never throws.
-   template<class CharT> 
-   bool save_to_file (const CharT *filename)
-   {
-      //Open output file
-      std::basic_ofstream< CharT, std::char_traits<CharT> > 
-         file(filename, std::ios::binary);
-      //Check and save
-      return file.is_open() && save_to_ostream (file);
-   }
-
-   //!Saves the managed segment memory to a std::ostream.
-   //!It's NOT thread-safe. Returns true if successful.
-   //!Never throws.
-   bool save_to_ostream (std::ostream &outstream)
-   {
-      return outstream.write(char_ptr_cast(this->get_address()), 
-                             (std::streamsize)this->get_size()).good();
-   }
-
    //!Returns a constant iterator to the index storing the
    //!named allocations. NOT thread-safe. Never throws.
    const_named_iterator named_begin() const
Modified: trunk/boost/interprocess/indexes/iset_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/iset_index.hpp	(original)
+++ trunk/boost/interprocess/indexes/iset_index.hpp	2007-10-25 02:33:50 EDT (Thu, 25 Oct 2007)
@@ -40,7 +40,9 @@
    typedef typename 
       segment_manager_base::void_pointer                       void_pointer;
    typedef typename bi::make_set_base_hook
-      <bi::void_pointer<void_pointer> >::type                  derivation_hook;
+      < bi::void_pointer<void_pointer>
+      , bi::optimize_size<true>
+      >::type                                                  derivation_hook;
 
    typedef typename MapConfig::template 
       intrusive_value_type<derivation_hook>::type              value_type;
Modified: trunk/boost/interprocess/indexes/iunordered_set_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/iunordered_set_index.hpp	(original)
+++ trunk/boost/interprocess/indexes/iunordered_set_index.hpp	2007-10-25 02:33:50 EDT (Thu, 25 Oct 2007)
@@ -42,7 +42,8 @@
       segment_manager_base::void_pointer              void_pointer;
 
    typedef typename bi::make_unordered_set_base_hook
-      < bi::void_pointer<void_pointer> >::type        derivation_hook;
+      < bi::void_pointer<void_pointer>
+      >::type        derivation_hook;
 
    typedef typename MapConfig::template 
       intrusive_value_type<derivation_hook>::type     value_type;
Modified: trunk/boost/interprocess/managed_heap_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_heap_memory.hpp	(original)
+++ trunk/boost/interprocess/managed_heap_memory.hpp	2007-10-25 02:33:50 EDT (Thu, 25 Oct 2007)
@@ -29,37 +29,6 @@
 namespace boost {
 namespace interprocess {
 
-/// @cond
-namespace detail {
-
-   //!This class defines an operator() that creates a heap memory
-   //!of the requested size. The rest of the parameters are
-   //!passed in the constructor. The class a template parameter
-   //!to be used with create_from_file/create_from_istream functions
-   //!of basic_named_object classes
-   class heap_mem_creator_t
-   {
-      public:
-      heap_mem_creator_t(std::vector<char> &heapmem)
-      : m_heapmem(heapmem){}
-
-      void *operator()(std::size_t size)
-      {
-         BOOST_TRY{
-            m_heapmem.resize(size, char(0));
-         }
-         BOOST_CATCH(...){
-            return 0;
-         }
-         BOOST_CATCH_END
-         return &m_heapmem[0];
-      }      
-      private:
-      std::vector<char> &m_heapmem;
-   };
-}  //namespace detail {
-/// @endcond
-
 //!A basic heap memory named object creation class. Initializes the 
 //!heap memory segment. Inherits all basic functionality from 
 //!basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>*/
Modified: trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp	(original)
+++ trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp	2007-10-25 02:33:50 EDT (Thu, 25 Oct 2007)
@@ -49,7 +49,7 @@
 //!the user can access the multiple buffers allocated in a single call
 template<class VoidPointer>
 class basic_multiallocation_iterator
-   :  public std::iterator<std::input_iterator_tag, char *>
+   :  public std::iterator<std::input_iterator_tag, char>
 {
    void unspecified_bool_type_func() const {}
    typedef void (basic_multiallocation_iterator::*unspecified_bool_type)() const;
@@ -59,7 +59,7 @@
             multi_allocation_next_ptr;
 
    public:
-   typedef char *       value_type;
+   typedef char         value_type;
    typedef value_type & reference;
    typedef value_type * pointer;
 
@@ -91,20 +91,14 @@
    bool operator!= (const basic_multiallocation_iterator& other) const
    { return !operator== (other); }
 
-   value_type operator*() const
-   {
-      value_type v = (char*)detail::get_pointer(next_alloc_.next_);
-      return v;
-   }
+   reference operator*() const
+   {  return *((char*)detail::get_pointer(next_alloc_.next_)); }
 
    operator unspecified_bool_type() const  
    {  return next_alloc_.next_? &basic_multiallocation_iterator::unspecified_bool_type_func : 0;   }
 
    pointer operator->() const
-   {
-      BOOST_ASSERT(0);
-      return 0;
-   }
+   { return &(*(*this)); }
 
    private:
    multi_allocation_next<VoidPointer> next_alloc_;
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-25 02:33:50 EDT (Thu, 25 Oct 2007)
@@ -90,6 +90,7 @@
    typedef typename bi::make_splay_set_base_hook
 #endif
       < bi::void_pointer<VoidPointer>
+      , bi::optimize_size<true>
       , bi::link_mode<bi::normal_link> >::type           TreeHook;
 
    typedef detail::multi_allocation_next<void_pointer>   multi_allocation_next_t;
Modified: trunk/boost/interprocess/offset_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/offset_ptr.hpp	(original)
+++ trunk/boost/interprocess/offset_ptr.hpp	2007-10-25 02:33:50 EDT (Thu, 25 Oct 2007)
@@ -23,8 +23,9 @@
 #include <boost/interprocess/detail/cast_tags.hpp>
 #include <boost/interprocess/detail/mpl.hpp>
 #include <boost/assert.hpp>
-#include <iterator>
 #include <ostream>
+#include <istream>
+#include <iterator>
 
 //!\file
 //!Describes a smart pointer that stores the offset between this pointer and
@@ -149,6 +150,9 @@
    pointer get()const
    {  return (pointer)this->get_pointer();   }
 
+   std::ptrdiff_t get_offset()
+   {  return m_offset;  }
+
    //!Pointer-like -> operator. It can return 0 pointer.
    //!Never throws.
    pointer operator->() const           
@@ -286,14 +290,14 @@
 template<class E, class T, class Y> 
 inline std::basic_ostream<E, T> & operator<< 
    (std::basic_ostream<E, T> & os, offset_ptr<Y> const & p)
-{  return os << p.get();   }
+{  return os << p.get_offset();   }
 
 //!operator>> 
 //!for offset ptr
 template<class E, class T, class Y> 
 inline std::basic_istream<E, T> & operator>> 
    (std::basic_istream<E, T> & is, offset_ptr<Y> & p)
-{  return is >> p.get();  }
+{  return is >> p.get_offset();  }
 
 //!std::ptrdiff_t + offset_ptr
 //!operation
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-25 02:33:50 EDT (Thu, 25 Oct 2007)
@@ -127,27 +127,40 @@
    interprocess_condition *condition() const
    {  return &static_cast<condition_holder*>(m_shmem.get_user_address())->cond_; }
 
+   template <class Lock>
+   class lock_inverter
+   {
+      Lock &l_;
+      public:
+      lock_inverter(Lock &l)
+         :  l_(l)
+      {}
+      void lock()    {   l_.unlock();   }
+      void unlock()  {   l_.lock();     }
+   };
+
    #if defined BOOST_INTERPROCESS_POSIX_SEMAPHORES && defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
    interprocess_mutex *mutex() const
    {  return &static_cast<condition_holder*>(m_shmem.get_user_address())->mutex_; }
 
    template <class Lock>
    void do_wait(Lock& lock)
-   {
-      scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
-      lock.unlock();
+   {  
+      lock_inverter<Lock> inverted_lock(lock);
+      //unlock internal first to avoid deadlock with near simultaneous waits
+      scoped_lock<lock_inverter<Lock> >   external_unlock(inverted_lock);
+      scoped_lock<interprocess_mutex>     internal_lock(*this->mutex());
       this->condition()->wait(internal_lock);
-      lock.lock();
    }
 
    template <class Lock>
    bool do_timed_wait(Lock& lock, const boost::posix_time::ptime &abs_time)
    {
-      scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
-      lock.unlock();
-      bool r = this->condition()->timed_wait(internal_lock, abs_time);
-      lock.lock();
-      return r;
+      //unlock internal first to avoid deadlock with near simultaneous waits
+      lock_inverter<Lock> inverted_lock(lock);
+      scoped_lock<lock_inverter<Lock> >   external_unlock(inverted_lock);
+      scoped_lock<interprocess_mutex>     internal_lock(*this->mutex());
+      return this->condition()->timed_wait(internal_lock, abs_time);
    }
    #endif