OpenWalnut 1.2.5
|
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