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