void LifeTimeManager::impl_registerApiCall(bool bLongLastingCall)
{ //only allowed if not disposed //do not acquire the mutex here because it will be acquired already
m_nAccessCount++; if(m_nAccessCount==1) //@todo? is it ok to wake some threads here while we have acquired the mutex?
m_aNoAccessCountCondition.reset();
void LifeTimeManager::impl_unregisterApiCall(std::unique_lock<std::mutex>& rGuard, bool bLongLastingCall)
{ //Mutex needs to be acquired exactly once //mutex may be released inbetween in special case of impl_apiCallCountReachedNull()
m_bInDispose = true; //adding any listener is not allowed anymore //new calls will not be accepted //still running calls have the freedom to finish their work without crash
OSL_ENSURE( !m_bDisposed, "dispose was called already" );
m_bDisposed = true;
} //no mutex is acquired
//wait until all still running calls have finished //the accessCount cannot grow anymore, because all calls will return after checking m_bDisposed
m_aNoAccessCountCondition.wait();
//we are the only ones working on our data now
returntrue; //--release all resources and references after calling this method successful
}
void CloseableLifeTimeManager::g_close_endTryClose()
{ //this method is called, if the try to close was not successful
std::unique_lock aGuard( m_aAccessMutex );
//Mutex needs to be acquired exactly once //mutex may be released inbetween in special case of impl_apiCallCountReachedNull()
impl_unregisterApiCall(aGuard, false);
}
void CloseableLifeTimeManager::g_close_isNeedToCancelLongLastingCalls( bool bDeliverOwnership, util::CloseVetoException const & ex )
{ //this method is called when no closelistener has had a veto during queryclosing //the method returns false, if nothing stands against closing anymore //it returns true, if some longlasting calls are running, which might be cancelled //it throws the given exception, if long calls are running but not cancelable
std::unique_lock aGuard( m_aAccessMutex ); //this count cannot grow after try of close has started, because we wait in all those methods for end of try closing if( !m_nLongLastingCallCount ) return;
//Mutex needs to be acquired exactly once //mutex may be released inbetween in special case of impl_apiCallCountReachedNull()
impl_unregisterApiCall(aGuard, false);
throw ex;
}
void CloseableLifeTimeManager::g_close_endTryClose_doClose()
{ //this method is called, if the try to close was successful
std::unique_lock aGuard( m_aAccessMutex );
//Mutex needs to be acquired exactly once //mutex may be released inbetween in special case of impl_apiCallCountReachedNull()
impl_unregisterApiCall(aGuard, false);
impl_doClose(aGuard);
}
void CloseableLifeTimeManager::impl_apiCallCountReachedNull(std::unique_lock<std::mutex>& rGuard)
{ //Mutex needs to be acquired exactly once //mutex will be released inbetween in impl_doClose() if( m_pCloseable && m_bOwnership )
impl_doClose(rGuard);
}
void CloseableLifeTimeManager::impl_doClose(std::unique_lock<std::mutex>& rGuard)
{ //Mutex needs to be acquired exactly once before calling impl_doClose()
if(m_bClosed) return; //behave as passive as possible, if disposed or closed already if( m_bDisposed || m_bInDispose ) return; //behave as passive as possible, if disposed or closed already
bool CloseableLifeTimeManager::impl_canStartApiCall()
{ //Mutex needs to be acquired exactly once before calling this method //the mutex will be released inbetween and reacquired
if( impl_isDisposed() ) returnfalse; //behave passive if already disposed if( m_bClosed ) returnfalse; //behave passive if closing is already done
//during try-close most calls need to wait for the decision while( m_bInTryClose )
{ //if someone tries to close this object at the moment //we need to wait for his end because the result of the preceding call //is relevant for our behaviour here
m_aAccessMutex.unlock();
m_aEndTryClosingCondition.wait(); //@todo??? this may block??? try closing
m_aAccessMutex.lock(); if( m_bDisposed || m_bInDispose || m_bClosed ) returnfalse; //return if closed already
} //mutex is acquired returntrue;
}
bool LifeTimeGuard::startApiCall(bool bLongLastingCall)
{ //Mutex needs to be acquired exactly once; will be released inbetween //mutex is required due to constructor of LifeTimeGuard
OSL_ENSURE( !m_bCallRegistered, "this method is only allowed ones" ); if(m_bCallRegistered) returnfalse;
//Mutex needs to be acquired exactly once; will be released inbetween if( !m_rManager.impl_canStartApiCall() ) returnfalse; //mutex is acquired
LifeTimeGuard::~LifeTimeGuard()
{ try
{ //do acquire the mutex if it was cleared before if (!m_guard.owns_lock())
m_guard.lock(); if(m_bCallRegistered)
{ //Mutex needs to be acquired exactly once //mutex may be released inbetween in special case of impl_apiCallCountReachedNull()
m_rManager.impl_unregisterApiCall(m_guard, m_bLongLastingCallRegistered);
}
} catch( uno::Exception& ex )
{ //@todo ? allow a uno::RuntimeException from dispose to travel through??
ex.Context.is(); //to avoid compilation warnings
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.