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     /**
00046      * Default constructor.
00047      */
00048     WSharedObject();
00049 
00050     /**
00051      * Destructor.
00052      */
00053     virtual ~WSharedObject();
00054 
00055     /**
00056      * Type for read tickets.
00057      */
00058     typedef boost::shared_ptr< WSharedObjectTicketRead< T > > ReadTicket;
00059 
00060     /**
00061      * Type for write tickets.
00062      */
00063     typedef boost::shared_ptr< WSharedObjectTicketWrite< T > > WriteTicket;
00064 
00065     /**
00066      * Returns a ticket to get read access to the contained data. After the ticket is freed, the read lock vanishes.
00067      *
00068      * \return the read ticket
00069      */
00070     ReadTicket getReadTicket() const;
00071 
00072     /**
00073      * Returns a ticket to get write access to the contained data. After the ticket is freed, the write lock vanishes.
00074      *
00075      * \param suppressNotify true if no notification should be send after unlocking.
00076      *
00077      * \return the ticket
00078      */
00079     WriteTicket getWriteTicket( bool suppressNotify = false ) const;
00080 
00081     /**
00082      * This condition fires whenever the encapsulated object changed. This is fired automatically by endWrite().
00083      *
00084      * \return the condition
00085      */
00086     boost::shared_ptr< WCondition > getChangeCondition() const;
00087 
00088 protected:
00089 
00090     /**
00091      * The object wrapped by this class. This member is mutable as the \ref getReadTicket and \ref getWriteTicket functions are const but need a
00092      * non-const reference to m_object.
00093      */
00094     mutable T m_object;
00095 
00096     /**
00097      * The lock to ensure thread safe access. This member is mutable as the \ref getReadTicket and \ref getWriteTicket functions are const but need a
00098      * non-const reference to m_lock.
00099      */
00100     mutable boost::shared_ptr< boost::shared_mutex > m_lock;
00101 
00102     /**
00103      * This condition set fires whenever the contained object changes. This corresponds to the Observable pattern.
00104      */
00105     boost::shared_ptr< WCondition > m_changeCondition;
00106 
00107 private:
00108 };
00109 
00110 template < typename T >
00111 WSharedObject< T >::WSharedObject():
00112     m_lock( new boost::shared_mutex ),
00113     m_changeCondition( new WCondition() )
00114 {
00115     // init members
00116 }
00117 
00118 template < typename T >
00119 WSharedObject< T >::~WSharedObject()
00120 {
00121     // clean up
00122 }
00123 
00124 template < typename T >
00125 boost::shared_ptr< WCondition > WSharedObject< T >::getChangeCondition() const
00126 {
00127     return m_changeCondition;
00128 }
00129 
00130 template < typename T >
00131 typename WSharedObject< T >::ReadTicket WSharedObject< T >::getReadTicket() const
00132 {
00133     return boost::shared_ptr< WSharedObjectTicketRead< T > >(
00134             new WSharedObjectTicketRead< T >( m_object, m_lock, boost::shared_ptr< WCondition >() )
00135     );
00136 }
00137 
00138 template < typename T >
00139 typename WSharedObject< T >::WriteTicket WSharedObject< T >::getWriteTicket( bool suppressNotify ) const
00140 {
00141     if( suppressNotify )
00142     {
00143         return boost::shared_ptr< WSharedObjectTicketWrite< T > >(
00144                 new WSharedObjectTicketWrite< T >( m_object, m_lock, boost::shared_ptr< WCondition >() )
00145         );
00146     }
00147     else
00148     {
00149         return boost::shared_ptr< WSharedObjectTicketWrite< T > >(
00150                 new WSharedObjectTicketWrite< T >( m_object, m_lock, m_changeCondition )
00151         );
00152     }
00153 }
00154 
00155 #endif  // WSHAREDOBJECT_H
00156 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends