1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #ifndef __FRAMEWORK_THREADHELP_GATE_HXX_ 29*cdf0e10cSrcweir #define __FRAMEWORK_THREADHELP_GATE_HXX_ 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 32*cdf0e10cSrcweir // my own includes 33*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include <threadhelp/inoncopyable.h> 36*cdf0e10cSrcweir #include <threadhelp/igate.h> 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 39*cdf0e10cSrcweir // interface includes 40*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 43*cdf0e10cSrcweir // other includes 44*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 45*cdf0e10cSrcweir #include <osl/mutex.hxx> 46*cdf0e10cSrcweir #include <osl/conditn.hxx> 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 49*cdf0e10cSrcweir // namespace 50*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir namespace framework{ 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 55*cdf0e10cSrcweir // const 56*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 59*cdf0e10cSrcweir // declarations 60*cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir /*-************************************************************************************************************//** 63*cdf0e10cSrcweir @short implement a gate to block multiple threads at same time or unblock all 64*cdf0e10cSrcweir @descr A gate can be used as a negative-condition! You can open a "door" - wait() will not block ... 65*cdf0e10cSrcweir or you can close it - wait() blocks till open() is called again. 66*cdf0e10cSrcweir As a special feature you can open the gate a little bit by sing openGap(). 67*cdf0e10cSrcweir Then all currently waiting threads are running immediately - but new ones are blocked! 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir @attention To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private! 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir @implements IGate 72*cdf0e10cSrcweir @base IGate 73*cdf0e10cSrcweir INonCopyable 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir @devstatus ready to use 76*cdf0e10cSrcweir *//*-*************************************************************************************************************/ 77*cdf0e10cSrcweir class Gate : public IGate 78*cdf0e10cSrcweir , private INonCopyable 79*cdf0e10cSrcweir { 80*cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------- 81*cdf0e10cSrcweir // public methods 82*cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------- 83*cdf0e10cSrcweir public: 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir /*-****************************************************************************************************//** 86*cdf0e10cSrcweir @short ctor 87*cdf0e10cSrcweir @descr These initialize the object right as an open gate. 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir @seealso - 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir @param - 92*cdf0e10cSrcweir @return - 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir @onerror - 95*cdf0e10cSrcweir *//*-*****************************************************************************************************/ 96*cdf0e10cSrcweir inline Gate() 97*cdf0e10cSrcweir : m_bClosed ( sal_False ) 98*cdf0e10cSrcweir , m_bGapOpen ( sal_False ) 99*cdf0e10cSrcweir { 100*cdf0e10cSrcweir open(); 101*cdf0e10cSrcweir } 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir /*-****************************************************************************************************//** 104*cdf0e10cSrcweir @short dtor 105*cdf0e10cSrcweir @descr Is user forget it - we open the gate ... 106*cdf0e10cSrcweir blocked threads can running ... but I don't know 107*cdf0e10cSrcweir if it's right - we are destroyed yet!? 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir @seealso - 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir @param - 112*cdf0e10cSrcweir @return - 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir @onerror - 115*cdf0e10cSrcweir *//*-*****************************************************************************************************/ 116*cdf0e10cSrcweir inline virtual ~Gate() 117*cdf0e10cSrcweir { 118*cdf0e10cSrcweir open(); 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir /*-****************************************************************************************************//** 122*cdf0e10cSrcweir @interface IGate 123*cdf0e10cSrcweir @short open the gate 124*cdf0e10cSrcweir @descr A wait() call will not block then. 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir @seealso method close() 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir @param - 129*cdf0e10cSrcweir @return - 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir @onerror - 132*cdf0e10cSrcweir *//*-*****************************************************************************************************/ 133*cdf0e10cSrcweir inline virtual void open() 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir // We must safe access to our internal member! 136*cdf0e10cSrcweir ::osl::MutexGuard aLock( m_aAccessLock ); 137*cdf0e10cSrcweir // Set condition -> wait don't block any longer -> gate is open 138*cdf0e10cSrcweir m_aPassage.set(); 139*cdf0e10cSrcweir // Check if operation was successful! 140*cdf0e10cSrcweir // Check returns false if condition isn't set => m_bClosed will be true then => we must return false; opening failed 141*cdf0e10cSrcweir m_bClosed = ( m_aPassage.check() == sal_False ); 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir /*-****************************************************************************************************//** 145*cdf0e10cSrcweir @interface IGate 146*cdf0e10cSrcweir @short close the gate 147*cdf0e10cSrcweir @descr A wait() call will block then. 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir @seealso method open() 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir @param - 152*cdf0e10cSrcweir @return - 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir @onerror - 155*cdf0e10cSrcweir *//*-*****************************************************************************************************/ 156*cdf0e10cSrcweir inline virtual void close() 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir // We must safe access to our internal member! 159*cdf0e10cSrcweir ::osl::MutexGuard aLock( m_aAccessLock ); 160*cdf0e10cSrcweir // Reset condition -> wait blocks now -> gate is closed 161*cdf0e10cSrcweir m_aPassage.reset(); 162*cdf0e10cSrcweir // Check if operation was successful! 163*cdf0e10cSrcweir // Check returns false if condition was reseted => m_bClosed will be true then => we can return true; closing ok 164*cdf0e10cSrcweir m_bClosed = ( m_aPassage.check() == sal_False ); 165*cdf0e10cSrcweir } 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir /*-****************************************************************************************************//** 168*cdf0e10cSrcweir @interface IGate 169*cdf0e10cSrcweir @short open gate for current waiting threads 170*cdf0e10cSrcweir @descr All current waiting threads stand in wait() at line "m_aPassage.wait()" ... 171*cdf0e10cSrcweir With this call you can open the passage for these waiting ones. 172*cdf0e10cSrcweir The "gap" is closed by any new thread which call wait() automaticly! 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir @seealso method wait() 175*cdf0e10cSrcweir @seealso method open() 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir @param - 178*cdf0e10cSrcweir @return - 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir @onerror - 181*cdf0e10cSrcweir *//*-*****************************************************************************************************/ 182*cdf0e10cSrcweir inline virtual void openGap() 183*cdf0e10cSrcweir { 184*cdf0e10cSrcweir // We must safe access to our internal member! 185*cdf0e10cSrcweir ::osl::MutexGuard aLock( m_aAccessLock ); 186*cdf0e10cSrcweir // Open passage for current waiting threads. 187*cdf0e10cSrcweir m_aPassage.set(); 188*cdf0e10cSrcweir // Check state of condition. 189*cdf0e10cSrcweir // If condition is set check() returns true => m_bGapOpen will be true too => we can use it as return value. 190*cdf0e10cSrcweir m_bGapOpen = ( m_aPassage.check() == sal_True ); 191*cdf0e10cSrcweir } 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir /*-****************************************************************************************************//** 194*cdf0e10cSrcweir @interface IGate 195*cdf0e10cSrcweir @short must be called to pass the gate 196*cdf0e10cSrcweir @descr If gate "open" => wait() will not block. 197*cdf0e10cSrcweir If gate "closed" => wait() will block till somewhere open it again. 198*cdf0e10cSrcweir If gap "open" => currently waiting threads unblocked, new ones blocked 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir @seealso method wait() 201*cdf0e10cSrcweir @seealso method open() 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir @param "pTimeOut", optional parameter to wait a certain time 204*cdf0e10cSrcweir @return true, if wait was successful (gate was opened) 205*cdf0e10cSrcweir false, if condition has an error or timeout was reached! 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir @onerror We return false. 208*cdf0e10cSrcweir *//*-*****************************************************************************************************/ 209*cdf0e10cSrcweir inline virtual sal_Bool wait( const TimeValue* pTimeOut = NULL ) 210*cdf0e10cSrcweir { 211*cdf0e10cSrcweir // We must safe access to our internal member! 212*cdf0e10cSrcweir ::osl::ClearableMutexGuard aLock( m_aAccessLock ); 213*cdf0e10cSrcweir // If gate not closed - caller can pass it. 214*cdf0e10cSrcweir sal_Bool bSuccessful = sal_True; 215*cdf0e10cSrcweir if( m_bClosed == sal_True ) 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir // Otherwise first new thread must close an open gap! 218*cdf0e10cSrcweir if( m_bGapOpen == sal_True ) 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir m_bGapOpen = sal_False; 221*cdf0e10cSrcweir m_aPassage.reset(); 222*cdf0e10cSrcweir } 223*cdf0e10cSrcweir // Then we must release used access lock - 224*cdf0e10cSrcweir // because next call will block ... 225*cdf0e10cSrcweir // and if we hold the access lock nobody else can use this object without a dadlock! 226*cdf0e10cSrcweir aLock.clear(); 227*cdf0e10cSrcweir // Wait for opening gate ... 228*cdf0e10cSrcweir bSuccessful = ( m_aPassage.wait( pTimeOut ) == ::osl::Condition::result_ok ); 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir return bSuccessful; 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------- 235*cdf0e10cSrcweir // private member 236*cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------- 237*cdf0e10cSrcweir private: 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir ::osl::Mutex m_aAccessLock ; 240*cdf0e10cSrcweir ::osl::Condition m_aPassage ; 241*cdf0e10cSrcweir sal_Bool m_bClosed ; 242*cdf0e10cSrcweir sal_Bool m_bGapOpen ; 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir }; // class Gate 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir } // namespace framework 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir #endif // #ifndef __FRAMEWORK_THREADHELP_GATE_HXX_ 249