diff options
author | Matúš Kukan <matus.kukan@collabora.com> | 2014-01-22 14:05:06 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-01-24 14:24:34 +0000 |
commit | ef597d80dc18f9662a50f3abad5d39d0fd76449e (patch) | |
tree | 343c0be676a4c41c76e1e14e3a3e48c9aa1329dd /framework | |
parent | 4b1ecc4c7da84eee69c583222b62afbf6afed3ab (diff) |
Introduce com.sun.star.task.theJobExecutor singleton.
To replace com.sun.star.task.JobExecutor single-instance service,
incorrectly converted in 748aa84e9808ad31c6ff6b71459525c82de10e58
[including changes by Stephan Bergmann <sbergman@redhat.com>]
Change-Id: I4cea2c63a20b5b22f6e1f822fb35fcc4d0397687
Reviewed-on: https://gerrit.libreoffice.org/7609
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Tested-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'framework')
-rw-r--r-- | framework/inc/pch/precompiled_fwk.hxx | 2 | ||||
-rw-r--r-- | framework/source/jobs/jobexecutor.cxx | 134 | ||||
-rw-r--r-- | framework/source/services/frame.cxx | 4 | ||||
-rw-r--r-- | framework/util/fwk.component | 1 |
4 files changed, 82 insertions, 59 deletions
diff --git a/framework/inc/pch/precompiled_fwk.hxx b/framework/inc/pch/precompiled_fwk.hxx index 4095d2a2c629..4d1790c3a1c1 100644 --- a/framework/inc/pch/precompiled_fwk.hxx +++ b/framework/inc/pch/precompiled_fwk.hxx @@ -179,7 +179,7 @@ #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> #include <com/sun/star/task/ErrorCodeRequest.hpp> #include <com/sun/star/task/InteractionHandler.hpp> -#include <com/sun/star/task/JobExecutor.hpp> +#include <com/sun/star/task/theJobExecutor.hpp> #include <com/sun/star/task/StatusIndicatorFactory.hpp> #include <com/sun/star/task/XAsyncJob.hpp> #include <com/sun/star/task/XInteractionAbort.hpp> diff --git a/framework/source/jobs/jobexecutor.cxx b/framework/source/jobs/jobexecutor.cxx index 7c8b7961ab26..f5605a2075b8 100644 --- a/framework/source/jobs/jobexecutor.cxx +++ b/framework/source/jobs/jobexecutor.cxx @@ -21,10 +21,6 @@ #include <jobs/joburl.hxx> #include <jobs/configaccess.hxx> #include <classes/converter.hxx> -#include <threadhelp/transactionguard.hxx> -#include <threadhelp/threadhelpbase.hxx> -#include <threadhelp/readguard.hxx> -#include <threadhelp/writeguard.hxx> #include <general.h> #include <stdtypes.h> @@ -41,7 +37,7 @@ #include <com/sun/star/document/XEventListener.hpp> #include <com/sun/star/frame/XModuleManager2.hpp> -#include <cppuhelper/implbase4.hxx> +#include <cppuhelper/compbase4.hxx> #include <cppuhelper/supportsservice.hxx> #include <unotools/configpaths.hxx> #include <rtl/ref.hxx> @@ -52,27 +48,26 @@ using namespace framework; namespace { +typedef cppu::WeakComponentImplHelper4< + css::lang::XServiceInfo + , css::task::XJobExecutor + , css::container::XContainerListener // => lang.XEventListener + , css::document::XEventListener > + Base; + /** @short implements a job executor, which can be triggered from any code @descr It uses the given trigger event to locate any registered job service inside the configuration and execute it. Of course it controls the liftime of such jobs too. */ -class JobExecutor : private ThreadHelpBase - , public ::cppu::WeakImplHelper4< - css::lang::XServiceInfo - , css::task::XJobExecutor - , css::container::XContainerListener // => lang.XEventListener - , css::document::XEventListener > +class JobExecutor : private osl::Mutex, public Base { private: /** reference to the uno service manager */ css::uno::Reference< css::uno::XComponentContext > m_xContext; - /** reference to the module info service */ - css::uno::Reference< css::frame::XModuleManager2 > m_xModuleManager; - /** cached list of all registered event names of cfg for call optimization. */ OUStringList m_lEvents; @@ -82,6 +77,8 @@ private: /** helper to allow us listen to the configuration without a cyclic dependency */ com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> m_xConfigListener; + virtual void SAL_CALL disposing() SAL_OVERRIDE; + public: JobExecutor( const css::uno::Reference< css::uno::XComponentContext >& xContext ); @@ -133,9 +130,8 @@ public: reference to the uno service manager */ JobExecutor::JobExecutor( /*IN*/ const css::uno::Reference< css::uno::XComponentContext >& xContext ) - : ThreadHelpBase (&Application::GetSolarMutex() ) + : Base (*static_cast<Mutex *>(this)) , m_xContext (xContext ) - , m_xModuleManager (css::frame::ModuleManager::create( m_xContext )) , m_aConfig (xContext, OUString::createFromAscii(JobData::EVENTCFG_ROOT) ) { } @@ -172,9 +168,24 @@ void JobExecutor::initListeners() JobExecutor::~JobExecutor() { - css::uno::Reference< css::container::XContainer > xNotifier(m_aConfig.cfg(), css::uno::UNO_QUERY); - if (xNotifier.is()) - xNotifier->removeContainerListener(m_xConfigListener); + disposing(); +} + +void JobExecutor::disposing() { + css::uno::Reference<css::container::XContainer> notifier; + css::uno::Reference<css::container::XContainerListener> listener; + { + osl::MutexGuard g(rBHelper.rMutex); + if (m_aConfig.getMode() != ConfigAccess::E_CLOSED) { + notifier.set(m_aConfig.cfg(), css::uno::UNO_QUERY); + listener = m_xConfigListener; + m_aConfig.close(); + } + m_xConfigListener.clear(); + } + if (notifier.is()) { + notifier->removeContainerListener(listener); + } } //________________________________ @@ -192,8 +203,10 @@ void SAL_CALL JobExecutor::trigger( const OUString& sEvent ) throw(css::uno::Run { SAL_INFO( "fwk", "fwk (as96863) JobExecutor::trigger()"); - /* SAFE { */ - ReadGuard aReadLock(m_aLock); + css::uno::Sequence< OUString > lJobs; + + /* SAFE */ { + osl::MutexGuard g(rBHelper.rMutex); // Optimization! // Check if the given event name exist inside configuration and reject wrong requests. @@ -204,17 +217,17 @@ void SAL_CALL JobExecutor::trigger( const OUString& sEvent ) throw(css::uno::Run // get list of all enabled jobs // The called static helper methods read it from the configuration and // filter disabled jobs using it's time stamp values. - css::uno::Sequence< OUString > lJobs = JobData::getEnabledJobsForEvent(m_xContext, sEvent); - - aReadLock.unlock(); - /* } SAFE */ + lJobs = JobData::getEnabledJobsForEvent(m_xContext, sEvent); + } /* SAFE */ // step over all enabled jobs and execute it sal_Int32 c = lJobs.getLength(); for (sal_Int32 j=0; j<c; ++j) { - /* SAFE { */ - aReadLock.lock(); + rtl::Reference<Job> pJob; + + /* SAFE */ { + SolarMutexGuard g2; JobData aCfg(m_xContext); aCfg.setEvent(sEvent, lJobs[j]); @@ -225,14 +238,11 @@ void SAL_CALL JobExecutor::trigger( const OUString& sEvent ) throw(css::uno::Run And freeing of such uno object is done by uno itself. So we have to use dynamic memory everytimes. */ - Job* pJob = new Job(m_xContext, css::uno::Reference< css::frame::XFrame >()); - css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY); + pJob = new Job(m_xContext, css::uno::Reference< css::frame::XFrame >()); pJob->setJobData(aCfg); + } /* SAFE */ - aReadLock.unlock(); - /* } SAFE */ - - pJob->execute(css::uno::Sequence< css::beans::NamedValue >()); + pJob->execute(css::uno::Sequence< css::beans::NamedValue >()); } } @@ -247,21 +257,21 @@ void SAL_CALL JobExecutor::notifyEvent( const css::document::EventObject& aEvent OUString EVENT_ON_DOCUMENT_OPENED("onDocumentOpened"); // Job UI event : OnNew or OnLoad OUString EVENT_ON_DOCUMENT_ADDED("onDocumentAdded"); // Job API event : OnCreate or OnLoadFinished - /* SAFE { */ - ReadGuard aReadLock(m_aLock); - + OUString aModuleIdentifier; ::comphelper::SequenceAsVector< JobData::TJob2DocEventBinding > lJobs; + /* SAFE */ { + osl::MutexGuard g(rBHelper.rMutex); + // Optimization! // Check if the given event name exist inside configuration and reject wrong requests. // This optimization supress using of the cfg api for getting event and job descriptions. // see using of m_lEvents.find() below ... // retrieve event context from event source - OUString aModuleIdentifier; try { - aModuleIdentifier = m_xModuleManager->identify( aEvent.Source ); + aModuleIdentifier = css::frame::ModuleManager::create( m_xContext )->identify( aEvent.Source ); } catch( const css::uno::Exception& ) {} @@ -289,9 +299,7 @@ void SAL_CALL JobExecutor::notifyEvent( const css::document::EventObject& aEvent // Add all jobs for "real" notified event too .-) if (m_lEvents.find(aEvent.EventName) != m_lEvents.end()) JobData::appendEnabledJobsForEvent(m_xContext, aEvent.EventName, lJobs); - - aReadLock.unlock(); - /* } SAFE */ + } /* SAFE */ // step over all enabled jobs and execute it ::comphelper::SequenceAsVector< JobData::TJob2DocEventBinding >::const_iterator pIt; @@ -299,8 +307,10 @@ void SAL_CALL JobExecutor::notifyEvent( const css::document::EventObject& aEvent pIt != lJobs.end() ; ++pIt ) { - /* SAFE { */ - aReadLock.lock(); + rtl::Reference<Job> pJob; + + /* SAFE */ { + SolarMutexGuard g2; const JobData::TJob2DocEventBinding& rBinding = *pIt; @@ -317,12 +327,9 @@ void SAL_CALL JobExecutor::notifyEvent( const css::document::EventObject& aEvent So we have to use dynamic memory everytimes. */ css::uno::Reference< css::frame::XModel > xModel(aEvent.Source, css::uno::UNO_QUERY); - Job* pJob = new Job(m_xContext, xModel); - css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY); + pJob = new Job(m_xContext, xModel); pJob->setJobData(aCfg); - - aReadLock.unlock(); - /* } SAFE */ + } /* SAFE */ pJob->execute(css::uno::Sequence< css::beans::NamedValue >()); } @@ -384,7 +391,7 @@ void SAL_CALL JobExecutor::elementReplaced( const css::container::ContainerEvent void SAL_CALL JobExecutor::disposing( const css::lang::EventObject& aEvent ) throw(css::uno::RuntimeException) { /* SAFE { */ - ReadGuard aReadLock(m_aLock); + osl::MutexGuard g(rBHelper.rMutex); css::uno::Reference< css::uno::XInterface > xCFG(m_aConfig.cfg(), css::uno::UNO_QUERY); if ( (xCFG == aEvent.Source ) && @@ -393,10 +400,28 @@ void SAL_CALL JobExecutor::disposing( const css::lang::EventObject& aEvent ) thr { m_aConfig.close(); } - aReadLock.unlock(); /* } SAFE */ } +struct Instance { + explicit Instance( + css::uno::Reference<css::uno::XComponentContext> const & context): + instance( + static_cast<cppu::OWeakObject *>(new JobExecutor(context))) + { + // 2nd phase initialization needed + static_cast<JobExecutor *>(static_cast<cppu::OWeakObject *> + (instance.get()))->initListeners(); + } + + rtl::Reference<css::uno::XInterface> instance; +}; + +struct Singleton: + public rtl::StaticWithArg< + Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton> +{}; + } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL @@ -404,12 +429,9 @@ com_sun_star_comp_framework_JobExecutor_get_implementation( css::uno::XComponentContext *context, css::uno::Sequence<css::uno::Any> const &) { - JobExecutor *inst = new JobExecutor(context); - css::uno::XInterface *acquired_inst = cppu::acquire(inst); - - inst->initListeners(); - - return acquired_inst; + css::uno::XInterface *inst = Singleton::get(context).instance.get(); + inst->acquire(); + return inst; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/services/frame.cxx b/framework/source/services/frame.cxx index 2bc93d6d67c8..0d04ba6fff11 100644 --- a/framework/source/services/frame.cxx +++ b/framework/source/services/frame.cxx @@ -60,7 +60,7 @@ #include <com/sun/star/frame/FrameSearchFlag.hpp> #include <com/sun/star/lang/DisposedException.hpp> #include <com/sun/star/task/StatusIndicatorFactory.hpp> -#include <com/sun/star/task/JobExecutor.hpp> +#include <com/sun/star/task/theJobExecutor.hpp> #include <com/sun/star/task/XJobExecutor.hpp> #include <com/sun/star/util/URLTransformer.hpp> #include <com/sun/star/util/XURLTransformer.hpp> @@ -2757,7 +2757,7 @@ void SAL_CALL Frame::windowShown( const css::lang::EventObject& ) throw(css::uno if (bMustBeTriggered) { css::uno::Reference< css::task::XJobExecutor > xExecutor - = css::task::JobExecutor::create( xContext ); + = css::task::theJobExecutor::get( xContext ); xExecutor->trigger( "onFirstVisibleTask" ); } } diff --git a/framework/util/fwk.component b/framework/util/fwk.component index e08b966311e9..cc977f9c71ee 100644 --- a/framework/util/fwk.component +++ b/framework/util/fwk.component @@ -59,6 +59,7 @@ <implementation name="com.sun.star.comp.framework.JobExecutor" constructor="com_sun_star_comp_framework_JobExecutor_get_implementation"> <service name="com.sun.star.task.JobExecutor"/> + <singleton name="com.sun.star.task.theJobExecutor"/> </implementation> <implementation name="com.sun.star.comp.framework.LangSelectionStatusbarController" constructor="com_sun_star_comp_framework_LangSelectionStatusbarController_get_implementation"> |