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 #include "WConditionSet.h" 00026 00027 WConditionSet::WConditionSet(): 00028 WCondition(), 00029 m_resetable( false ), 00030 m_autoReset( false ), 00031 m_fired( false ), 00032 m_notifier( boost::bind( &WConditionSet::conditionFired, this ) ) 00033 { 00034 } 00035 00036 WConditionSet::~WConditionSet() 00037 { 00038 // get write lock 00039 boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_conditionSetLock ); 00040 00041 // clean conditions list 00042 // NOTE: we need to disconnect here. 00043 for( ConditionConnectionMap::iterator it = m_conditionSet.begin(); it != m_conditionSet.end(); ++it ) 00044 { 00045 ( *it ).second.disconnect(); 00046 } 00047 00048 m_conditionSet.clear(); 00049 lock.unlock(); 00050 } 00051 00052 void WConditionSet::add( boost::shared_ptr< WCondition > condition ) 00053 { 00054 // get write lock 00055 boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_conditionSetLock ); 00056 00057 if( !m_conditionSet.count( condition ) ) 00058 { 00059 // create a new pair, the condition and its connection object. 00060 // this is needed since remove needs the connection to disconnect the notifier again 00061 m_conditionSet.insert( ConditionConnectionPair( condition, condition->subscribeSignal( m_notifier ) ) ); 00062 } 00063 00064 lock.unlock(); 00065 } 00066 00067 void WConditionSet::remove( boost::shared_ptr< WCondition > condition ) 00068 { 00069 // get write lock 00070 boost::unique_lock<boost::shared_mutex> lock = boost::unique_lock<boost::shared_mutex>( m_conditionSetLock ); 00071 00072 // get the element 00073 ConditionConnectionMap::iterator it = m_conditionSet.find( condition ); 00074 if( it != m_conditionSet.end() ) 00075 { 00076 ( *it ).second.disconnect(); 00077 m_conditionSet.erase( it ); 00078 } 00079 00080 lock.unlock(); 00081 } 00082 00083 void WConditionSet::conditionFired() 00084 { 00085 m_fired = true; 00086 notify(); 00087 } 00088 00089 void WConditionSet::wait() const 00090 { 00091 if( !m_resetable || !m_fired ) 00092 { 00093 WCondition::wait(); 00094 } 00095 00096 if( m_autoReset ) 00097 { 00098 reset(); 00099 } 00100 } 00101 00102 void WConditionSet::reset() const 00103 { 00104 m_fired = false; 00105 } 00106 00107 void WConditionSet::setResetable( bool resetable, bool autoReset ) 00108 { 00109 m_autoReset = autoReset; 00110 m_resetable = resetable; 00111 } 00112 00113 bool WConditionSet::isResetable() 00114 { 00115 return m_resetable; 00116 } 00117