Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55786 - in sandbox/fmhess: boost/generic_ptr libs/generic_ptr/test
From: fmhess_at_[hidden]
Date: 2009-08-26 11:42:59


Author: fmhess
Date: 2009-08-26 11:42:59 EDT (Wed, 26 Aug 2009)
New Revision: 55786
URL: http://svn.boost.org/trac/boost/changeset/55786

Log:
Went back to more generic monitor template parameter MutexPointer,
instead of always using a shared<Mutex>. Used specialized factory
function to avoid creating an unsafe default mutex pointer when
the MutexPointer isn't a shared_ptr<T>-like type.

Text files modified:
   sandbox/fmhess/boost/generic_ptr/monitor.hpp | 110 +++++++++++++++++++++++++--------------
   sandbox/fmhess/libs/generic_ptr/test/basic_generic_pointer_test.cpp | 23 ++++++++
   sandbox/fmhess/libs/generic_ptr/test/cloning_monitor_test.cpp | 6 +
   3 files changed, 96 insertions(+), 43 deletions(-)

Modified: sandbox/fmhess/boost/generic_ptr/monitor.hpp
==============================================================================
--- sandbox/fmhess/boost/generic_ptr/monitor.hpp (original)
+++ sandbox/fmhess/boost/generic_ptr/monitor.hpp 2009-08-26 11:42:59 EDT (Wed, 26 Aug 2009)
@@ -14,10 +14,10 @@
 #ifndef BOOST_GENERIC_PTR_MONITOR_HPP_INCLUDED
 #define BOOST_GENERIC_PTR_MONITOR_HPP_INCLUDED
 
+#include <boost/generic_ptr/detail/unique_lock.hpp>
 #include <boost/generic_ptr/monitor_locks.hpp> // for monitor_unique_lock
 #include <boost/generic_ptr/pointer_cast.hpp>
 #include <boost/generic_ptr/pointer_traits.hpp>
-#include <boost/generic_ptr/detail/unique_lock.hpp>
 #include <boost/generic_ptr/shared.hpp>
 #include <boost/mpl/identity.hpp>
 #include <boost/type_traits/is_convertible.hpp>
@@ -27,12 +27,40 @@
 namespace boost
 {
   class mutex;
+ template<typename T>
+ class shared_ptr;
 
   namespace generic_ptr
   {
- template<typename T, typename Mutex = boost::mutex>
+ template<typename T>
+ class shared;
+
+ template<typename MutexSharedPointer>
+ MutexSharedPointer create_default_mutex(mpl::identity<MutexSharedPointer> /*adl_helper*/,
+ typename shared_pointer_traits<MutexSharedPointer>::weak_type * /*SFINAE_helper*/ = 0)
+ {
+ // FIXME: replace with make_shared
+ typedef typename shared_pointer_traits<MutexSharedPointer>::value_type mutex_type;
+ mutex_type *mutex = new mutex_type();
+ MutexSharedPointer result;
+ try
+ {
+ result.reset(mutex);
+ }
+ catch(...)
+ {
+ delete mutex;
+ throw;
+ }
+ return result;
+ }
+
+ template<typename T, typename MutexPointer = shared<boost::mutex*> >
     class monitor
     {
+ public:
+ typedef typename pointer_traits<MutexPointer>::value_type mutex_type;
+ private:
       typedef monitor this_type; // for detail/operator_bool.hpp
 
       // we could use monitor_unique_lock, but this should be slightly faster
@@ -63,19 +91,19 @@
         moving_monitor_lock(moving_monitor_lock & other);
 
         T _object_p;
- detail::unique_lock<Mutex> _lock;
+ detail::unique_lock<mutex_type> _lock;
       };
 
     public:
       typedef typename pointer_traits<T>::value_type value_type;
       typedef T pointer;
       typedef typename pointer_traits<T>::reference reference;
- typedef Mutex mutex_type;
+ typedef MutexPointer mutex_pointer_type;
 
       template<typename ValueType>
       struct rebind
       {
- typedef monitor<typename generic_ptr::rebind<pointer, ValueType>::other, Mutex > other;
+ typedef monitor<typename generic_ptr::rebind<pointer, ValueType>::other, MutexPointer > other;
       };
 
       monitor(): px(), _mutex_p()
@@ -84,13 +112,13 @@
       explicit monitor
       (
         U p,
- const shared<Mutex*> & mutex_p = shared<Mutex*>(new Mutex())
+ const MutexPointer & mutex_p = create_default_mutex(typename mpl::identity<MutexPointer>())
       ): px( p ), _mutex_p(mutex_p)
       {}
       template<typename U>
       monitor
       (
- const monitor<U, Mutex> & other
+ const monitor<U, MutexPointer> & other
 #ifndef BOOST_NO_SFINAE
         , typename enable_if<is_convertible<U, T> >::type * = 0
 #endif // BOOST_NO_SFINAE
@@ -141,13 +169,13 @@
       {
         monitor().swap(*this);
       }
- template<typename U> void reset(U object_p, const shared<mutex_type*> &mutex_p)
+ template<typename U> void reset(U object_p, const mutex_pointer_type &mutex_p)
       {
         monitor(object_p, mutex_p).swap(*this);
       }
 
       pointer get() const {return px;}
- shared<mutex_type*> get_shared_mutex() const {return _mutex_p;}
+ MutexPointer get_mutex_pointer() const {return _mutex_p;}
       mutex_type& get_mutex_ref() const {return *_mutex_p;}
 
 // implicit conversion to "bool"
@@ -162,15 +190,15 @@
 // to work in the absence of member template friends. (Matthew Langston)
 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
     private:
- template<typename Y, typename OtherMutex> friend class monitor;
+ template<typename Y, typename OtherMutexPointer> friend class monitor;
 #endif
 
       pointer px;
- shared<mutex_type*> _mutex_p;
+ mutex_pointer_type _mutex_p;
     };
 
- template<typename T, typename Mutex>
- T get_pointer(const monitor<T, Mutex> &mp)
+ template<typename T, typename MutexPointer>
+ T get_pointer(const monitor<T, MutexPointer> &mp)
     {
       //FIXME: should get_pointer return a monitor lock?
       // if it does not, it will not be safe to use monitor as "this" pointer with bind.
@@ -179,82 +207,82 @@
     }
 
     // casts
- template<typename ToValueType, typename U, typename Mutex>
- typename rebind<monitor<U, Mutex>, ToValueType>::other static_pointer_cast
+ template<typename ToValueType, typename U, typename MutexPointer>
+ typename rebind<monitor<U, MutexPointer>, ToValueType>::other static_pointer_cast
     (
- monitor<U, Mutex> const & p,
+ monitor<U, MutexPointer> const & p,
       mpl::identity<ToValueType> to_type_iden = mpl::identity<ToValueType>()
     )
     {
- typedef typename rebind<monitor<U, Mutex>, ToValueType>::other result_type;
- return result_type(static_pointer_cast(p.get(), to_type_iden), p.get_shared_mutex());
+ typedef typename rebind<monitor<U, MutexPointer>, ToValueType>::other result_type;
+ return result_type(static_pointer_cast(p.get(), to_type_iden), p.get_mutex_pointer());
     }
- template<typename ToValueType, typename U, typename Mutex>
- typename rebind<monitor<U, Mutex>, ToValueType>::other const_pointer_cast
+ template<typename ToValueType, typename U, typename MutexPointer>
+ typename rebind<monitor<U, MutexPointer>, ToValueType>::other const_pointer_cast
     (
- monitor<U, Mutex> const & p,
+ monitor<U, MutexPointer> const & p,
        mpl::identity<ToValueType> to_type_iden = mpl::identity<ToValueType>()
     )
     {
- typedef typename rebind<monitor<U, Mutex>, ToValueType>::other result_type;
- return result_type(const_pointer_cast(p.get(), to_type_iden), p.get_shared_mutex());
+ typedef typename rebind<monitor<U, MutexPointer>, ToValueType>::other result_type;
+ return result_type(const_pointer_cast(p.get(), to_type_iden), p.get_mutex_pointer());
     }
- template<typename ToValueType, typename U, typename Mutex>
- typename rebind<monitor<U, Mutex>, ToValueType>::other dynamic_pointer_cast
+ template<typename ToValueType, typename U, typename MutexPointer>
+ typename rebind<monitor<U, MutexPointer>, ToValueType>::other dynamic_pointer_cast
     (
- monitor<U, Mutex> const & p,
+ monitor<U, MutexPointer> const & p,
         mpl::identity<ToValueType> to_type_iden = mpl::identity<ToValueType>()
     )
     {
- typedef typename rebind<monitor<U, Mutex>, ToValueType>::other result_type;
- return result_type(dynamic_pointer_cast(p.get(), to_type_iden), p.get_shared_mutex());
+ typedef typename rebind<monitor<U, MutexPointer>, ToValueType>::other result_type;
+ return result_type(dynamic_pointer_cast(p.get(), to_type_iden), p.get_mutex_pointer());
     }
 
     // comparisons
- template<class T, class U, typename Mutex> inline bool operator==(monitor<T, Mutex> const & a, monitor<U, Mutex> const & b)
+ template<class T, class U, typename MutexPointer> inline bool operator==(monitor<T, MutexPointer> const & a, monitor<U, MutexPointer> const & b)
     {
       return a.get() == b.get();
     }
- template<class T, class U, typename Mutex> inline bool operator!=(monitor<T, Mutex> const & a, monitor<U, Mutex> const & b)
+ template<class T, class U, typename MutexPointer> inline bool operator!=(monitor<T, MutexPointer> const & a, monitor<U, MutexPointer> const & b)
     {
       return a.get() != b.get();
     }
- template<class T, class U, typename Mutex> inline bool operator==(monitor<T, Mutex> const & a, U const & b)
+ template<class T, class U, typename MutexPointer> inline bool operator==(monitor<T, MutexPointer> const & a, U const & b)
     {
       return a.get() == b;
     }
- template<class T, class U, typename Mutex> inline bool operator!=(monitor<T, Mutex> const & a, U const & b)
+ template<class T, class U, typename MutexPointer> inline bool operator!=(monitor<T, MutexPointer> const & a, U const & b)
     {
       return a.get() != b;
     }
- template<class T, class U, typename Mutex> inline bool operator==(T const & a, monitor<U, Mutex> const & b)
+ template<class T, class U, typename MutexPointer> inline bool operator==(T const & a, monitor<U, MutexPointer> const & b)
     {
       return a == b.get();
     }
- template<class T, class U, typename Mutex> inline bool operator!=(T const & a, monitor<U, Mutex> const & b)
+ template<class T, class U, typename MutexPointer> inline bool operator!=(T const & a, monitor<U, MutexPointer> const & b)
     {
       return a != b.get();
     }
     #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
     // Resolve the ambiguity between our op!= and the one in rel_ops
- template<class T, typename Mutex> inline bool operator!=(monitor<T, Mutex> const & a, monitor<T, Mutex> const & b)
+ template<class T, typename MutexPointer> inline bool operator!=(monitor<T, MutexPointer> const & a, monitor<T, MutexPointer> const & b)
     {
       return a.get() != b.get();
     }
     #endif
- template<class T, typename Mutex> inline bool operator<(monitor<T, Mutex> const & a, monitor<T, Mutex> const & b)
+ template<class T, typename MutexPointer> inline bool operator<(monitor<T, MutexPointer> const & a, monitor<T, MutexPointer> const & b)
     {
- return std::less<typename monitor<T, Mutex>::pointer>()(a.get(), b.get());
+ return std::less<typename monitor<T, MutexPointer>::pointer>()(a.get(), b.get());
     }
 
     // construct_clone overload for safe (mutex locked) use with generic_ptr::cloning
- template<typename GenericPointer, typename Mutex>
- monitor<GenericPointer, Mutex> construct_clone(void *location, const monitor<GenericPointer, Mutex> &p)
+ template<typename GenericPointer, typename MutexPointer>
+ monitor<GenericPointer, MutexPointer> construct_clone(void *location, const monitor<GenericPointer, MutexPointer> &p)
     {
       if(get_plain_old_pointer(p) == 0) return p;
- monitor_unique_lock<monitor<GenericPointer, Mutex> > lock(p);
+ monitor_unique_lock<monitor<GenericPointer, MutexPointer> > lock(p);
       using boost::generic_ptr::construct_clone;
- return monitor<GenericPointer, Mutex>(construct_clone(location, p.get()));
+ return monitor<GenericPointer, MutexPointer>(construct_clone(location, p.get()));
     }
   } // namespace generic_ptr
 } // namespace boost

Modified: sandbox/fmhess/libs/generic_ptr/test/basic_generic_pointer_test.cpp
==============================================================================
--- sandbox/fmhess/libs/generic_ptr/test/basic_generic_pointer_test.cpp (original)
+++ sandbox/fmhess/libs/generic_ptr/test/basic_generic_pointer_test.cpp 2009-08-26 11:42:59 EDT (Wed, 26 Aug 2009)
@@ -216,6 +216,29 @@
     conversion_to_void_test(p);
     overload_resolution_test(p);
   }
+ { // monitor with plain old mutex pointer
+ X x;
+ boost::mutex mut;
+ bgp::monitor<X*, boost::mutex*> p(&x, &mut);
+ member_access_test(p);
+ // dereference_test(p); // monitors don't support dereference
+ rebind_test(p);
+ cast_test(p);
+ conversion_to_base_test(p);
+ conversion_to_void_test(p);
+ overload_resolution_test(p);
+ }
+ { // monitor with boost::shared_ptr mutex pointer
+ X x;
+ bgp::monitor<X*, boost::shared_ptr<boost::mutex> > p(&x);
+ member_access_test(p);
+ // dereference_test(p); // monitors don't support dereference
+ rebind_test(p);
+ cast_test(p);
+ conversion_to_base_test(p);
+ conversion_to_void_test(p);
+ overload_resolution_test(p);
+ }
   {
     bgp::shared<X*> p(new X());
     member_access_test(p);

Modified: sandbox/fmhess/libs/generic_ptr/test/cloning_monitor_test.cpp
==============================================================================
--- sandbox/fmhess/libs/generic_ptr/test/cloning_monitor_test.cpp (original)
+++ sandbox/fmhess/libs/generic_ptr/test/cloning_monitor_test.cpp 2009-08-26 11:42:59 EDT (Wed, 26 Aug 2009)
@@ -13,6 +13,8 @@
 #include <boost/generic_ptr/cloning.hpp>
 #include <boost/generic_ptr/monitor.hpp>
 
+namespace bgp = boost::generic_ptr;
+//
 class event_counting_mutex
 {
 public:
@@ -42,8 +44,8 @@
 
 void clone_test()
 {
- typedef boost::generic_ptr::monitor<int*, event_counting_mutex> monitor_type;
- typedef boost::generic_ptr::cloning<monitor_type> cloning_monitor_type;
+ typedef bgp::monitor<int*, bgp::shared<event_counting_mutex*> > monitor_type;
+ typedef bgp::cloning<monitor_type> cloning_monitor_type;
   cloning_monitor_type p0(new int());
   BOOST_TEST(p0.get().get_mutex_ref().lock_count == 0);
   BOOST_TEST(p0.get().get_mutex_ref().unlock_count == 0);


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