2007-04-03 14:46:41 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
|
|
*
|
|
|
|
* $RCSfile: ConfigurationUpdater.cxx,v $
|
|
|
|
*
|
2008-04-03 12:29:54 +00:00
|
|
|
* $Revision: 1.4 $
|
2007-04-03 14:46:41 +00:00
|
|
|
*
|
2008-04-03 12:29:54 +00:00
|
|
|
* last change: $Author: kz $ $Date: 2008-04-03 13:29:54 $
|
2007-04-03 14:46:41 +00:00
|
|
|
*
|
|
|
|
* The Contents of this file are made available subject to
|
|
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#include "precompiled_sd.hxx"
|
|
|
|
|
|
|
|
#include "ConfigurationUpdater.hxx"
|
|
|
|
#include "ConfigurationTracer.hxx"
|
|
|
|
#include "ConfigurationClassifier.hxx"
|
2008-04-03 12:29:54 +00:00
|
|
|
#include "ConfigurationControllerBroadcaster.hxx"
|
2007-04-03 14:46:41 +00:00
|
|
|
#include "framework/Configuration.hxx"
|
|
|
|
#include "framework/FrameworkHelper.hxx"
|
|
|
|
|
|
|
|
#include <comphelper/scopeguard.hxx>
|
|
|
|
|
|
|
|
#include <boost/bind.hpp>
|
|
|
|
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
using namespace ::com::sun::star::uno;
|
|
|
|
using namespace ::com::sun::star::drawing::framework;
|
|
|
|
using ::sd::framework::FrameworkHelper;
|
2008-04-03 12:29:54 +00:00
|
|
|
using ::rtl::OUString;
|
|
|
|
using ::std::vector;
|
2007-04-03 14:46:41 +00:00
|
|
|
|
|
|
|
#undef VERBOSE
|
|
|
|
//#define VERBOSE 2
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
static const sal_Int32 snShortTimeout (100);
|
|
|
|
static const sal_Int32 snNormalTimeout (1000);
|
|
|
|
static const sal_Int32 snLongTimeout (10000);
|
|
|
|
static const sal_Int32 snShortTimeoutCountThreshold (1);
|
|
|
|
static const sal_Int32 snNormalTimeoutCountThreshold (5);
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace sd { namespace framework {
|
|
|
|
|
|
|
|
|
|
|
|
//===== ConfigurationUpdaterLock ==============================================
|
|
|
|
|
|
|
|
class ConfigurationUpdaterLock
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ConfigurationUpdaterLock (ConfigurationUpdater& rUpdater)
|
|
|
|
: mrUpdater(rUpdater) { mrUpdater.LockUpdates(); }
|
|
|
|
~ConfigurationUpdaterLock(void) { mrUpdater.UnlockUpdates(); }
|
|
|
|
private:
|
|
|
|
ConfigurationUpdater& mrUpdater;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//===== ConfigurationUpdater ==================================================
|
|
|
|
|
|
|
|
ConfigurationUpdater::ConfigurationUpdater (
|
2008-04-03 12:29:54 +00:00
|
|
|
const ::boost::shared_ptr<ConfigurationControllerBroadcaster>& rpBroadcaster,
|
|
|
|
const ::boost::shared_ptr<ConfigurationControllerResourceManager>& rpResourceManager,
|
|
|
|
const Reference<XControllerManager>& rxControllerManager)
|
2007-04-03 14:46:41 +00:00
|
|
|
: mxControllerManager(),
|
2008-04-03 12:29:54 +00:00
|
|
|
mpBroadcaster(rpBroadcaster),
|
2007-04-03 14:46:41 +00:00
|
|
|
mxCurrentConfiguration(Reference<XConfiguration>(new Configuration(NULL, false))),
|
|
|
|
mxRequestedConfiguration(),
|
|
|
|
mbUpdatePending(false),
|
|
|
|
mbUpdateBeingProcessed(false),
|
|
|
|
mnLockCount(0),
|
|
|
|
maUpdateTimer(),
|
2008-04-03 12:29:54 +00:00
|
|
|
mnFailedUpdateCount(0),
|
|
|
|
mpResourceManager(rpResourceManager)
|
2007-04-03 14:46:41 +00:00
|
|
|
{
|
|
|
|
// Prepare the timer that is started when after an update the current
|
|
|
|
// and the requested configuration differ. With the timer we try
|
|
|
|
// updates until the two configurations are the same.
|
|
|
|
maUpdateTimer.SetTimeout(snNormalTimeout);
|
|
|
|
maUpdateTimer.SetTimeoutHdl(LINK(this,ConfigurationUpdater,TimeoutHandler));
|
2008-04-03 12:29:54 +00:00
|
|
|
SetControllerManager(rxControllerManager);
|
2007-04-03 14:46:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ConfigurationUpdater::~ConfigurationUpdater (void)
|
|
|
|
{
|
|
|
|
maUpdateTimer.Stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ConfigurationUpdater::SetControllerManager(
|
|
|
|
const Reference<XControllerManager>& rxControllerManager)
|
|
|
|
{
|
|
|
|
mxControllerManager = rxControllerManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ConfigurationUpdater::RequestUpdate (
|
|
|
|
const Reference<XConfiguration>& rxRequestedConfiguration)
|
|
|
|
{
|
|
|
|
mxRequestedConfiguration = rxRequestedConfiguration;
|
|
|
|
|
|
|
|
// Find out whether we really can update the configuration.
|
|
|
|
if (IsUpdatePossible())
|
|
|
|
{
|
2008-04-03 12:29:54 +00:00
|
|
|
#if defined VERBOSE && VERBOSE>=1
|
|
|
|
OSL_TRACE("UpdateConfiguration start");
|
|
|
|
#endif
|
|
|
|
|
2007-04-03 14:46:41 +00:00
|
|
|
// Call UpdateConfiguration while that is possible and while someone
|
|
|
|
// set mbUpdatePending to true in the middle of it.
|
|
|
|
do
|
|
|
|
{
|
|
|
|
UpdateConfiguration();
|
|
|
|
|
|
|
|
if (mbUpdatePending && IsUpdatePossible())
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
while (false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mbUpdatePending = true;
|
|
|
|
#if defined VERBOSE && VERBOSE>=1
|
|
|
|
OSL_TRACE("scheduling update for later");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Reference<XConfiguration> ConfigurationUpdater::GetCurrentConfiguration (void) const
|
|
|
|
{
|
|
|
|
return mxCurrentConfiguration;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-04-03 12:29:54 +00:00
|
|
|
Reference<XConfiguration> ConfigurationUpdater::GetRequestedConfiguration (void) const
|
|
|
|
{
|
|
|
|
return mxRequestedConfiguration;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-04-03 14:46:41 +00:00
|
|
|
bool ConfigurationUpdater::IsUpdatePossible (void)
|
|
|
|
{
|
|
|
|
return ! mbUpdateBeingProcessed
|
|
|
|
&& mxControllerManager.is()
|
|
|
|
&& mnLockCount==0
|
|
|
|
&& mxRequestedConfiguration.is()
|
|
|
|
&& mxCurrentConfiguration.is();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ConfigurationUpdater::UpdateConfiguration (void)
|
|
|
|
{
|
|
|
|
#if defined VERBOSE && VERBOSE>=1
|
|
|
|
OSL_TRACE("UpdateConfiguration update");
|
|
|
|
#endif
|
|
|
|
SetUpdateBeingProcessed(true);
|
|
|
|
comphelper::ScopeGuard aScopeGuard (
|
2008-04-03 12:29:54 +00:00
|
|
|
::boost::bind(&ConfigurationUpdater::SetUpdateBeingProcessed, this, false));
|
2007-04-03 14:46:41 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
mbUpdatePending = false;
|
|
|
|
|
2008-04-03 12:29:54 +00:00
|
|
|
CleanRequestedConfiguration();
|
2007-04-03 14:46:41 +00:00
|
|
|
ConfigurationClassifier aClassifier(mxRequestedConfiguration, mxCurrentConfiguration);
|
|
|
|
if (aClassifier.Partition())
|
|
|
|
{
|
|
|
|
#if defined VERBOSE && VERBOSE>=2
|
|
|
|
OSL_TRACE("ConfigurationUpdater::UpdateConfiguration(");
|
|
|
|
ConfigurationTracer::TraceConfiguration(
|
|
|
|
mxRequestedConfiguration, "requested configuration");
|
|
|
|
ConfigurationTracer::TraceConfiguration(
|
|
|
|
mxCurrentConfiguration, "current configuration");
|
|
|
|
#endif
|
|
|
|
// Notify the begining of the update.
|
|
|
|
ConfigurationChangeEvent aEvent;
|
|
|
|
aEvent.Type = FrameworkHelper::msConfigurationUpdateStartEvent;
|
|
|
|
aEvent.Configuration = mxRequestedConfiguration;
|
2008-04-03 12:29:54 +00:00
|
|
|
mpBroadcaster->NotifyListeners(aEvent);
|
2007-04-03 14:46:41 +00:00
|
|
|
|
|
|
|
// Do the actual update. All exceptions are caught and ignored,
|
|
|
|
// so that the the end of the update is notified always.
|
|
|
|
try
|
|
|
|
{
|
2008-01-29 07:19:22 +00:00
|
|
|
if (mnLockCount == 0)
|
|
|
|
UpdateCore(aClassifier);
|
2007-04-03 14:46:41 +00:00
|
|
|
}
|
|
|
|
catch(RuntimeException)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// Notify the end of the update.
|
|
|
|
aEvent.Type = FrameworkHelper::msConfigurationUpdateEndEvent;
|
2008-04-03 12:29:54 +00:00
|
|
|
mpBroadcaster->NotifyListeners(aEvent);
|
2007-04-03 14:46:41 +00:00
|
|
|
|
|
|
|
CheckUpdateSuccess();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#if defined VERBOSE && VERBOSE>0
|
|
|
|
OSL_TRACE("nothing to do");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (RuntimeException e)
|
|
|
|
{
|
|
|
|
OSL_TRACE("caught exception while updating the current configuration");
|
|
|
|
DBG_ASSERT(false, "caught exception while updating the current configuration");
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined VERBOSE && VERBOSE>0
|
|
|
|
OSL_TRACE("ConfigurationUpdater::UpdateConfiguration)");
|
|
|
|
OSL_TRACE("UpdateConfiguration end");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-04-03 12:29:54 +00:00
|
|
|
void ConfigurationUpdater::CleanRequestedConfiguration (void)
|
|
|
|
{
|
|
|
|
if (mxControllerManager.is())
|
|
|
|
{
|
|
|
|
// Request the deactivation of pure anchors that have no child.
|
|
|
|
vector<Reference<XResourceId> > aResourcesToDeactivate;
|
|
|
|
CheckPureAnchors(mxRequestedConfiguration, aResourcesToDeactivate);
|
|
|
|
if (aResourcesToDeactivate.size() > 0)
|
|
|
|
{
|
|
|
|
Reference<XConfigurationController> xCC (
|
|
|
|
mxControllerManager->getConfigurationController());
|
|
|
|
vector<Reference<XResourceId> >::iterator iId;
|
|
|
|
for (iId=aResourcesToDeactivate.begin(); iId!=aResourcesToDeactivate.end(); ++iId)
|
|
|
|
if (iId->is())
|
|
|
|
xCC->requestResourceDeactivation(*iId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-04-03 14:46:41 +00:00
|
|
|
void ConfigurationUpdater::CheckUpdateSuccess (void)
|
|
|
|
{
|
|
|
|
// When the two configurations differ then start the timer to call
|
|
|
|
// another update later.
|
|
|
|
if ( ! AreConfigurationsEquivalent(mxCurrentConfiguration, mxRequestedConfiguration))
|
|
|
|
{
|
|
|
|
if (mnFailedUpdateCount <= snShortTimeoutCountThreshold)
|
|
|
|
maUpdateTimer.SetTimeout(snShortTimeout);
|
|
|
|
else if (mnFailedUpdateCount < snNormalTimeoutCountThreshold)
|
|
|
|
maUpdateTimer.SetTimeout(snNormalTimeout);
|
|
|
|
else
|
|
|
|
maUpdateTimer.SetTimeout(snLongTimeout);
|
|
|
|
++mnFailedUpdateCount;
|
|
|
|
maUpdateTimer.Start();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Update was successfull. Reset the failed update count.
|
|
|
|
mnFailedUpdateCount = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ConfigurationUpdater::UpdateCore (const ConfigurationClassifier& rClassifier)
|
|
|
|
{
|
2008-04-03 12:29:54 +00:00
|
|
|
try
|
|
|
|
{
|
2007-04-03 14:46:41 +00:00
|
|
|
#if defined VERBOSE && VERBOSE>=2
|
2008-04-03 12:29:54 +00:00
|
|
|
rClassifier.TraceResourceIdVector(
|
|
|
|
"requested but not current resources:", rClassifier.GetC1minusC2());
|
|
|
|
rClassifier.TraceResourceIdVector(
|
|
|
|
"current but not requested resources:", rClassifier.GetC2minusC1());
|
|
|
|
rClassifier.TraceResourceIdVector(
|
|
|
|
"requested and current resources:", rClassifier.GetC1andC2());
|
2007-04-03 14:46:41 +00:00
|
|
|
#endif
|
|
|
|
|
2008-04-03 12:29:54 +00:00
|
|
|
// Updating of the sub controllers is done in two steps. In the
|
|
|
|
// first the sub controllers typically shut down resources that are
|
|
|
|
// not requested anymore. In the second the sub controllers
|
|
|
|
// typically set up resources that have been newly requested.
|
|
|
|
mpResourceManager->DeactivateResources(rClassifier.GetC2minusC1(), mxCurrentConfiguration);
|
|
|
|
mpResourceManager->ActivateResources(rClassifier.GetC1minusC2(), mxCurrentConfiguration);
|
2007-04-03 14:46:41 +00:00
|
|
|
|
|
|
|
#if defined VERBOSE && VERBOSE>=2
|
2008-04-03 12:29:54 +00:00
|
|
|
OSL_TRACE("ConfigurationController::UpdateConfiguration)");
|
|
|
|
ConfigurationTracer::TraceConfiguration(
|
|
|
|
mxRequestedConfiguration, "requested configuration");
|
|
|
|
ConfigurationTracer::TraceConfiguration(
|
|
|
|
mxCurrentConfiguration, "current configuration");
|
2007-04-03 14:46:41 +00:00
|
|
|
#endif
|
|
|
|
|
2008-04-03 12:29:54 +00:00
|
|
|
// Deactivate pure anchors that have no child.
|
|
|
|
vector<Reference<XResourceId> > aResourcesToDeactivate;
|
|
|
|
CheckPureAnchors(mxCurrentConfiguration, aResourcesToDeactivate);
|
|
|
|
if (aResourcesToDeactivate.size() > 0)
|
|
|
|
mpResourceManager->DeactivateResources(aResourcesToDeactivate, mxCurrentConfiguration);
|
|
|
|
}
|
|
|
|
catch(RuntimeException)
|
2007-04-03 14:46:41 +00:00
|
|
|
{
|
2008-04-03 12:29:54 +00:00
|
|
|
OSL_ASSERT(false);
|
2007-04-03 14:46:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-04-03 12:29:54 +00:00
|
|
|
void ConfigurationUpdater::CheckPureAnchors (
|
|
|
|
const Reference<XConfiguration>& rxConfiguration,
|
|
|
|
vector<Reference<XResourceId> >& rResourcesToDeactivate)
|
2007-04-03 14:46:41 +00:00
|
|
|
{
|
2008-04-03 12:29:54 +00:00
|
|
|
if ( ! rxConfiguration.is())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Get a list of all resources in the configuration.
|
|
|
|
Sequence<Reference<XResourceId> > aResources(
|
|
|
|
rxConfiguration->getResources(
|
|
|
|
NULL, OUString(), AnchorBindingMode_INDIRECT));
|
|
|
|
sal_Int32 nCount (aResources.getLength());
|
|
|
|
|
|
|
|
// Prepare the list of pure anchors that have to be deactivated.
|
|
|
|
rResourcesToDeactivate.clear();
|
|
|
|
|
|
|
|
// Iterate over the list in reverse order because when there is a chain
|
|
|
|
// of pure anchors with only the last one having no child then the whole
|
|
|
|
// list has to be deactivated.
|
|
|
|
sal_Int32 nIndex (nCount-1);
|
|
|
|
while (nIndex >= 0)
|
2007-04-03 14:46:41 +00:00
|
|
|
{
|
2008-04-03 12:29:54 +00:00
|
|
|
const Reference<XResourceId> xResourceId (aResources[nIndex]);
|
|
|
|
const Reference<XResource> xResource (
|
|
|
|
mpResourceManager->GetResource(xResourceId).mxResource);
|
|
|
|
bool bDeactiveCurrentResource (false);
|
|
|
|
|
|
|
|
// Skip all resources that are no pure anchors.
|
|
|
|
if (xResource.is() && xResource->isAnchorOnly())
|
2007-04-03 14:46:41 +00:00
|
|
|
{
|
2008-04-03 12:29:54 +00:00
|
|
|
// When xResource is not an anchor of the the next resource in
|
|
|
|
// the list then it is the anchor of no resource at all.
|
|
|
|
if (nIndex == nCount-1)
|
2007-04-03 14:46:41 +00:00
|
|
|
{
|
2008-04-03 12:29:54 +00:00
|
|
|
// No following anchors, deactivate this one, then remove it
|
|
|
|
// from the list.
|
|
|
|
bDeactiveCurrentResource = true;
|
2007-04-03 14:46:41 +00:00
|
|
|
}
|
2008-04-03 12:29:54 +00:00
|
|
|
else
|
2007-04-03 14:46:41 +00:00
|
|
|
{
|
2008-04-03 12:29:54 +00:00
|
|
|
const Reference<XResourceId> xPrevResourceId (aResources[nIndex+1]);
|
|
|
|
if ( ! xPrevResourceId.is()
|
|
|
|
|| ! xPrevResourceId->isBoundTo(xResourceId, AnchorBindingMode_DIRECT))
|
|
|
|
{
|
|
|
|
// The previous resource (id) does not exist or is not bound to
|
|
|
|
// the current anchor.
|
|
|
|
bDeactiveCurrentResource = true;
|
|
|
|
}
|
2007-04-03 14:46:41 +00:00
|
|
|
}
|
|
|
|
}
|
2008-04-03 12:29:54 +00:00
|
|
|
|
|
|
|
if (bDeactiveCurrentResource)
|
|
|
|
{
|
|
|
|
#if defined VERBOSE && VERBOSE>=2
|
|
|
|
OSL_TRACE("deactiving pure anchor %s because it has no children",
|
|
|
|
OUStringToOString(
|
|
|
|
FrameworkHelper::ResourceIdToString(xResourceId),
|
|
|
|
RTL_TEXTENCODING_UTF8).getStr());
|
|
|
|
#endif
|
|
|
|
// Erase element from current configuration.
|
|
|
|
for (sal_Int32 nI=nIndex; nI<nCount-2; ++nI)
|
|
|
|
aResources[nI] = aResources[nI+1];
|
|
|
|
nCount -= 1;
|
|
|
|
|
|
|
|
rResourcesToDeactivate.push_back(xResourceId);
|
|
|
|
}
|
|
|
|
nIndex -= 1;
|
2007-04-03 14:46:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ConfigurationUpdater::LockUpdates (void)
|
|
|
|
{
|
|
|
|
++mnLockCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ConfigurationUpdater::UnlockUpdates (void)
|
|
|
|
{
|
|
|
|
--mnLockCount;
|
|
|
|
if (mnLockCount == 0 && mbUpdatePending)
|
|
|
|
{
|
|
|
|
RequestUpdate(mxRequestedConfiguration);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
::boost::shared_ptr<ConfigurationUpdaterLock> ConfigurationUpdater::GetLock (void)
|
|
|
|
{
|
|
|
|
return ::boost::shared_ptr<ConfigurationUpdaterLock>(new ConfigurationUpdaterLock(*this));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ConfigurationUpdater::SetUpdateBeingProcessed (bool bValue)
|
|
|
|
{
|
|
|
|
mbUpdateBeingProcessed = bValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IMPL_LINK(ConfigurationUpdater, TimeoutHandler, Timer*, EMPTYARG)
|
|
|
|
{
|
|
|
|
OSL_TRACE("configuration update timer");
|
|
|
|
if ( ! mbUpdateBeingProcessed
|
|
|
|
&& mxCurrentConfiguration.is()
|
|
|
|
&& mxRequestedConfiguration.is())
|
|
|
|
{
|
|
|
|
if ( ! AreConfigurationsEquivalent(mxCurrentConfiguration, mxRequestedConfiguration))
|
|
|
|
{
|
|
|
|
OSL_TRACE("configurations differ, requesting update");
|
|
|
|
RequestUpdate(mxRequestedConfiguration);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} } // end of namespace sd::framework
|