OpenWalnut  1.4.0
WSharedObject.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WSHAREDOBJECT_H
00026 #define WSHAREDOBJECT_H
00027 
00028 #include <boost/thread.hpp>
00029 
00030 #include "WCondition.h"
00031 #include "WSharedObjectTicket.h"
00032 #include "WSharedObjectTicketRead.h"
00033 #include "WSharedObjectTicketWrite.h"
00034 
00035 /**
00036  * Wrapper around an object/type for thread safe sharing of objects among multiple threads. The advantage of this class over WFlag
00037  * is, that WFlag just protects simple get/set operations, while this class can protect a whole bunch of operations on the
00038  * encapsulated object.
00039  */
00040 template < typename T >
00041 class WSharedObject
00042 {
00043 public:
00044     /**
00045      * Default constructor.
00046      */
00047     WSharedObject();
00048 
00049     /**
00050      * Destructor.
00051      */
00052     virtual ~WSharedObject();
00053 
00054     /**
00055      * The type protected by this shared object class
00056      */
00057     typedef T ValueT;
00058 
00059     /**
00060      * Type for read tickets.
00061      */
00062     typedef boost::shared_ptr< WSharedObjectTicketRead< T > > ReadTicket;
00063 
00064     /**
00065      * Type for write tickets.
00066      */
00067     typedef boost::shared_ptr< WSharedObjectTicketWrite< T > > WriteTicket;
00068 
00069     /**
00070      * Shared pointer abbreviation.
00071      */
00072     typedef boost::shared_ptr< WSharedObject< T > > SPtr;
00073 
00074     /**
00075      * Const shared ptr abbreviation.
00076      */
00077     typedef boost::shared_ptr< WSharedObject< T > > ConstSPtr;
00078 
00079     /**
00080      * Returns a ticket to get read access to the contained data. After the ticket is freed, the read lock vanishes.
00081      *
00082      * \return the read ticket
00083      */
00084     ReadTicket getReadTicket() const;
00085 
00086     /**
00087      * Returns a ticket to get write access to the contained data. After the ticket is freed, the write lock vanishes.
00088      *
00089      * \param suppressNotify true if no notification should be send after unlocking.
00090      *
00091      * \return the ticket
00092      */
00093     WriteTicket getWriteTicket( bool suppressNotify = false ) const;
00094 
00095     /**
00096      * This condition fires whenever the encapsulated object changed. This is fired automatically by endWrite().
00097      *
00098      * \return the condition
00099      */
00100     boost::shared_ptr< WCondition > getChangeCondition() const;
00101 
00102 protected:
00103     /**
00104      * The object wrapped by this class. This member is mutable as the \ref getReadTicket and \ref getWriteTicket functions are const but need a
00105      * non-const reference to m_object.
00106      */
00107     mutable T m_object;
00108 
00109     /**
00110      * The lock to ensure thread safe access. This member is mutable as the \ref getReadTicket and \ref getWriteTicket functions are const but need a
00111      * non-const reference to m_lock.
00112      */
00113     mutable boost::shared_ptr< boost::shared_mutex > m_lock;
00114 
00115     /**
00116      * This condition set fires whenever the contained object changes. This corresponds to the Observable pattern.
00117      */
00118     boost::shared_ptr< WCondition > m_changeCondition;
00119 
00120 private:
00121 };
00122 
00123 template < typename T >
00124 WSharedObject< T >::WSharedObject():
00125     m_lock( new boost::shared_mutex ),
00126     m_changeCondition( new WCondition() )
00127 {
00128     // init members
00129 }
00130 
00131 template < typename T >
00132 WSharedObject< T >::~WSharedObject()
00133 {
00134     // clean up
00135 }
00136 
00137 template < typename T >
00138 boost::shared_ptr< WCondition > WSharedObject< T >::getChangeCondition() const
00139 {
00140     return m_changeCondition;
00141 }
00142 
00143 template < typename T >
00144 typename WSharedObject< T >::ReadTicket WSharedObject< T >::getReadTicket() const
00145 {
00146     return boost::shared_ptr< WSharedObjectTicketRead< T > >(
00147             new WSharedObjectTicketRead< T >( m_object, m_lock, boost::shared_ptr< WCondition >() )
00148     );
00149 }
00150 
00151 template < typename T >
00152 typename WSharedObject< T >::WriteTicket WSharedObject< T >::getWriteTicket( bool suppressNotify ) const
00153 {
00154     if( suppressNotify )
00155     {
00156         return boost::shared_ptr< WSharedObjectTicketWrite< T > >(
00157                 new WSharedObjectTicketWrite< T >( m_object, m_lock, boost::shared_ptr< WCondition >() )
00158         );
00159     }
00160     else
00161     {
00162         return boost::shared_ptr< WSharedObjectTicketWrite< T > >(
00163                 new WSharedObjectTicketWrite< T >( m_object, m_lock, m_changeCondition )
00164         );
00165     }
00166 }
00167 
00168 #endif  // WSHAREDOBJECT_H
00169