1*efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*efeef26fSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*efeef26fSAndrew Rist * or more contributor license agreements. See the NOTICE file
5*efeef26fSAndrew Rist * distributed with this work for additional information
6*efeef26fSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*efeef26fSAndrew Rist * to you under the Apache License, Version 2.0 (the
8*efeef26fSAndrew Rist * "License"); you may not use this file except in compliance
9*efeef26fSAndrew Rist * with the License. You may obtain a copy of the License at
10*efeef26fSAndrew Rist *
11*efeef26fSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*efeef26fSAndrew Rist *
13*efeef26fSAndrew Rist * Unless required by applicable law or agreed to in writing,
14*efeef26fSAndrew Rist * software distributed under the License is distributed on an
15*efeef26fSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*efeef26fSAndrew Rist * KIND, either express or implied. See the License for the
17*efeef26fSAndrew Rist * specific language governing permissions and limitations
18*efeef26fSAndrew Rist * under the License.
19*efeef26fSAndrew Rist *
20*efeef26fSAndrew Rist *************************************************************/
21*efeef26fSAndrew Rist
22*efeef26fSAndrew Rist
23cdf0e10cSrcweir #include "precompiled_sw.hxx"
24cdf0e10cSrcweir #include <finalthreadmanager.hxx>
25cdf0e10cSrcweir
26cdf0e10cSrcweir #ifndef _OSL_THREAD_HXX_
27cdf0e10cSrcweir #include <osl/thread.hxx>
28cdf0e10cSrcweir #endif
29cdf0e10cSrcweir #include <errhdl.hxx>
30cdf0e10cSrcweir #include <pausethreadstarting.hxx>
31cdf0e10cSrcweir #include <swthreadjoiner.hxx>
32cdf0e10cSrcweir
33cdf0e10cSrcweir #include <com/sun/star/frame/XDesktop.hpp>
34cdf0e10cSrcweir #include <rtl/ustring.hxx>
35cdf0e10cSrcweir #include <com/sun/star/frame/XFramesSupplier.hpp>
36cdf0e10cSrcweir
37cdf0e10cSrcweir namespace css = ::com::sun::star;
38cdf0e10cSrcweir
39cdf0e10cSrcweir /** thread to cancel a give list of cancellable jobs
40cdf0e10cSrcweir
41cdf0e10cSrcweir helper class for FinalThreadManager
42cdf0e10cSrcweir
43cdf0e10cSrcweir @author OD
44cdf0e10cSrcweir */
45cdf0e10cSrcweir class CancelJobsThread : public osl::Thread
46cdf0e10cSrcweir {
47cdf0e10cSrcweir public:
CancelJobsThread(std::list<css::uno::Reference<css::util::XCancellable>> aJobs)48cdf0e10cSrcweir CancelJobsThread( std::list< css::uno::Reference< css::util::XCancellable > > aJobs )
49cdf0e10cSrcweir : osl::Thread(),
50cdf0e10cSrcweir maMutex(),
51cdf0e10cSrcweir maJobs( aJobs ),
52cdf0e10cSrcweir mbAllJobsCancelled( false ),
53cdf0e10cSrcweir mbStopped( false )
54cdf0e10cSrcweir {
55cdf0e10cSrcweir }
56cdf0e10cSrcweir
~CancelJobsThread()57cdf0e10cSrcweir virtual ~CancelJobsThread() {}
58cdf0e10cSrcweir
59cdf0e10cSrcweir void addJobs( std::list< css::uno::Reference< css::util::XCancellable > >& rJobs );
60cdf0e10cSrcweir
61cdf0e10cSrcweir bool allJobsCancelled() const;
62cdf0e10cSrcweir
63cdf0e10cSrcweir void stopWhenAllJobsCancelled();
64cdf0e10cSrcweir
65cdf0e10cSrcweir private:
66cdf0e10cSrcweir
67cdf0e10cSrcweir bool existJobs() const;
68cdf0e10cSrcweir
69cdf0e10cSrcweir css::uno::Reference< css::util::XCancellable > getNextJob();
70cdf0e10cSrcweir
71cdf0e10cSrcweir bool stopped() const;
72cdf0e10cSrcweir
73cdf0e10cSrcweir virtual void SAL_CALL run();
74cdf0e10cSrcweir
75cdf0e10cSrcweir mutable osl::Mutex maMutex;
76cdf0e10cSrcweir
77cdf0e10cSrcweir std::list< css::uno::Reference< css::util::XCancellable > > maJobs;
78cdf0e10cSrcweir
79cdf0e10cSrcweir bool mbAllJobsCancelled;
80cdf0e10cSrcweir bool mbStopped;
81cdf0e10cSrcweir };
82cdf0e10cSrcweir
addJobs(std::list<css::uno::Reference<css::util::XCancellable>> & rJobs)83cdf0e10cSrcweir void CancelJobsThread::addJobs( std::list< css::uno::Reference< css::util::XCancellable > >& rJobs )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
86cdf0e10cSrcweir
87cdf0e10cSrcweir maJobs.insert( maJobs.end(), rJobs.begin(), rJobs.end() );
88cdf0e10cSrcweir mbAllJobsCancelled = !maJobs.empty();
89cdf0e10cSrcweir }
90cdf0e10cSrcweir
existJobs() const91cdf0e10cSrcweir bool CancelJobsThread::existJobs() const
92cdf0e10cSrcweir {
93cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
94cdf0e10cSrcweir
95cdf0e10cSrcweir return !maJobs.empty();
96cdf0e10cSrcweir }
97cdf0e10cSrcweir
allJobsCancelled() const98cdf0e10cSrcweir bool CancelJobsThread::allJobsCancelled() const
99cdf0e10cSrcweir {
100cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
101cdf0e10cSrcweir
102cdf0e10cSrcweir return maJobs.empty() && mbAllJobsCancelled;
103cdf0e10cSrcweir }
stopWhenAllJobsCancelled()104cdf0e10cSrcweir void CancelJobsThread::stopWhenAllJobsCancelled()
105cdf0e10cSrcweir {
106cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
107cdf0e10cSrcweir
108cdf0e10cSrcweir mbStopped = true;
109cdf0e10cSrcweir }
110cdf0e10cSrcweir
getNextJob()111cdf0e10cSrcweir css::uno::Reference< css::util::XCancellable > CancelJobsThread::getNextJob()
112cdf0e10cSrcweir {
113cdf0e10cSrcweir css::uno::Reference< css::util::XCancellable > xRet;
114cdf0e10cSrcweir
115cdf0e10cSrcweir {
116cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
117cdf0e10cSrcweir
118cdf0e10cSrcweir if ( !maJobs.empty() )
119cdf0e10cSrcweir {
120cdf0e10cSrcweir xRet = maJobs.front();
121cdf0e10cSrcweir maJobs.pop_front();
122cdf0e10cSrcweir }
123cdf0e10cSrcweir }
124cdf0e10cSrcweir
125cdf0e10cSrcweir return xRet;
126cdf0e10cSrcweir }
127cdf0e10cSrcweir
stopped() const128cdf0e10cSrcweir bool CancelJobsThread::stopped() const
129cdf0e10cSrcweir {
130cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
131cdf0e10cSrcweir
132cdf0e10cSrcweir return mbStopped;
133cdf0e10cSrcweir }
134cdf0e10cSrcweir
run()135cdf0e10cSrcweir void SAL_CALL CancelJobsThread::run()
136cdf0e10cSrcweir {
137cdf0e10cSrcweir while ( !stopped() )
138cdf0e10cSrcweir {
139cdf0e10cSrcweir while ( existJobs() )
140cdf0e10cSrcweir {
141cdf0e10cSrcweir css::uno::Reference< css::util::XCancellable > aJob( getNextJob() );
142cdf0e10cSrcweir if ( aJob.is() )
143cdf0e10cSrcweir {
144cdf0e10cSrcweir aJob->cancel();
145cdf0e10cSrcweir }
146cdf0e10cSrcweir }
147cdf0e10cSrcweir
148cdf0e10cSrcweir mbAllJobsCancelled = true;
149cdf0e10cSrcweir
150cdf0e10cSrcweir {
151cdf0e10cSrcweir TimeValue aSleepTime;
152cdf0e10cSrcweir aSleepTime.Seconds = 1;
153cdf0e10cSrcweir aSleepTime.Nanosec = 0;
154cdf0e10cSrcweir osl_waitThread( &aSleepTime );
155cdf0e10cSrcweir }
156cdf0e10cSrcweir }
157cdf0e10cSrcweir }
158cdf0e10cSrcweir
159cdf0e10cSrcweir /** thread to terminate office, when all jobs are cancelled.
160cdf0e10cSrcweir
161cdf0e10cSrcweir helper class for FinalThreadManager
162cdf0e10cSrcweir
163cdf0e10cSrcweir @author OD
164cdf0e10cSrcweir */
165cdf0e10cSrcweir class TerminateOfficeThread : public osl::Thread
166cdf0e10cSrcweir {
167cdf0e10cSrcweir public:
TerminateOfficeThread(CancelJobsThread & rCancelJobsThread,css::uno::Reference<css::uno::XComponentContext> const & xContext)168cdf0e10cSrcweir TerminateOfficeThread( CancelJobsThread& rCancelJobsThread,
169cdf0e10cSrcweir css::uno::Reference< css::uno::XComponentContext > const & xContext )
170cdf0e10cSrcweir : osl::Thread(),
171cdf0e10cSrcweir maMutex(),
172cdf0e10cSrcweir mrCancelJobsThread( rCancelJobsThread ),
173cdf0e10cSrcweir mbStopOfficeTermination( false ),
174cdf0e10cSrcweir mxContext( xContext )
175cdf0e10cSrcweir {
176cdf0e10cSrcweir }
177cdf0e10cSrcweir
~TerminateOfficeThread()178cdf0e10cSrcweir virtual ~TerminateOfficeThread() {}
179cdf0e10cSrcweir
180cdf0e10cSrcweir void StopOfficeTermination();
181cdf0e10cSrcweir
182cdf0e10cSrcweir private:
183cdf0e10cSrcweir
184cdf0e10cSrcweir virtual void SAL_CALL run();
185cdf0e10cSrcweir virtual void SAL_CALL onTerminated();
186cdf0e10cSrcweir
187cdf0e10cSrcweir bool OfficeTerminationStopped();
188cdf0e10cSrcweir
189cdf0e10cSrcweir void PerformOfficeTermination();
190cdf0e10cSrcweir
191cdf0e10cSrcweir osl::Mutex maMutex;
192cdf0e10cSrcweir
193cdf0e10cSrcweir const CancelJobsThread& mrCancelJobsThread;
194cdf0e10cSrcweir
195cdf0e10cSrcweir bool mbStopOfficeTermination;
196cdf0e10cSrcweir
197cdf0e10cSrcweir css::uno::Reference< css::uno::XComponentContext > mxContext;
198cdf0e10cSrcweir };
199cdf0e10cSrcweir
StopOfficeTermination()200cdf0e10cSrcweir void TerminateOfficeThread::StopOfficeTermination()
201cdf0e10cSrcweir {
202cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
203cdf0e10cSrcweir
204cdf0e10cSrcweir mbStopOfficeTermination = true;
205cdf0e10cSrcweir }
206cdf0e10cSrcweir
OfficeTerminationStopped()207cdf0e10cSrcweir bool TerminateOfficeThread::OfficeTerminationStopped()
208cdf0e10cSrcweir {
209cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
210cdf0e10cSrcweir
211cdf0e10cSrcweir return mbStopOfficeTermination;
212cdf0e10cSrcweir }
213cdf0e10cSrcweir
run()214cdf0e10cSrcweir void SAL_CALL TerminateOfficeThread::run()
215cdf0e10cSrcweir {
216cdf0e10cSrcweir while ( !OfficeTerminationStopped() )
217cdf0e10cSrcweir {
218cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
219cdf0e10cSrcweir
220cdf0e10cSrcweir if ( mrCancelJobsThread.allJobsCancelled() )
221cdf0e10cSrcweir {
222cdf0e10cSrcweir break;
223cdf0e10cSrcweir }
224cdf0e10cSrcweir }
225cdf0e10cSrcweir
226cdf0e10cSrcweir if ( !OfficeTerminationStopped() )
227cdf0e10cSrcweir {
228cdf0e10cSrcweir PerformOfficeTermination();
229cdf0e10cSrcweir }
230cdf0e10cSrcweir }
231cdf0e10cSrcweir
PerformOfficeTermination()232cdf0e10cSrcweir void TerminateOfficeThread::PerformOfficeTermination()
233cdf0e10cSrcweir {
234cdf0e10cSrcweir css::uno::Reference< css::frame::XFramesSupplier > xTasksSupplier(
235cdf0e10cSrcweir mxContext->getServiceManager()->createInstanceWithContext(
236cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop") ),
237cdf0e10cSrcweir mxContext ),
238cdf0e10cSrcweir css::uno::UNO_QUERY );
239cdf0e10cSrcweir if ( !xTasksSupplier.is() )
240cdf0e10cSrcweir {
241cdf0e10cSrcweir ASSERT( false, "<TerminateOfficeThread::PerformOfficeTermination()> - no XFramesSupplier!" );
242cdf0e10cSrcweir return;
243cdf0e10cSrcweir }
244cdf0e10cSrcweir
245cdf0e10cSrcweir css::uno::Reference< css::container::XElementAccess > xList( xTasksSupplier->getFrames(), css::uno::UNO_QUERY );
246cdf0e10cSrcweir if ( !xList.is() )
247cdf0e10cSrcweir {
248cdf0e10cSrcweir ASSERT( false, "<TerminateOfficeThread::PerformOfficeTermination()> - no XElementAccess!" );
249cdf0e10cSrcweir return;
250cdf0e10cSrcweir }
251cdf0e10cSrcweir
252cdf0e10cSrcweir if ( !xList->hasElements() )
253cdf0e10cSrcweir {
254cdf0e10cSrcweir css::uno::Reference< css::frame::XDesktop > xDesktop( xTasksSupplier, css::uno::UNO_QUERY );
255cdf0e10cSrcweir if ( xDesktop.is() && !OfficeTerminationStopped() )
256cdf0e10cSrcweir {
257cdf0e10cSrcweir xDesktop->terminate();
258cdf0e10cSrcweir }
259cdf0e10cSrcweir }
260cdf0e10cSrcweir }
261cdf0e10cSrcweir
onTerminated()262cdf0e10cSrcweir void SAL_CALL TerminateOfficeThread::onTerminated()
263cdf0e10cSrcweir {
264cdf0e10cSrcweir if ( OfficeTerminationStopped() )
265cdf0e10cSrcweir {
266cdf0e10cSrcweir delete this;
267cdf0e10cSrcweir }
268cdf0e10cSrcweir }
269cdf0e10cSrcweir
270cdf0e10cSrcweir
271cdf0e10cSrcweir /** class FinalThreadManager
272cdf0e10cSrcweir
273cdf0e10cSrcweir @author OD
274cdf0e10cSrcweir */
FinalThreadManager(css::uno::Reference<css::uno::XComponentContext> const & context)275cdf0e10cSrcweir FinalThreadManager::FinalThreadManager(css::uno::Reference< css::uno::XComponentContext > const & context)
276cdf0e10cSrcweir : m_xContext(context),
277cdf0e10cSrcweir maMutex(),
278cdf0e10cSrcweir maThreads(),
279cdf0e10cSrcweir mpCancelJobsThread( 0 ),
280cdf0e10cSrcweir mpTerminateOfficeThread( 0 ),
281cdf0e10cSrcweir mpPauseThreadStarting( 0 ),
282cdf0e10cSrcweir mbRegisteredAtDesktop( false )
283cdf0e10cSrcweir {
284cdf0e10cSrcweir
285cdf0e10cSrcweir }
286cdf0e10cSrcweir
registerAsListenerAtDesktop()287cdf0e10cSrcweir void FinalThreadManager::registerAsListenerAtDesktop()
288cdf0e10cSrcweir {
289cdf0e10cSrcweir css::uno::Reference< css::frame::XDesktop > xDesktop(
290cdf0e10cSrcweir m_xContext->getServiceManager()->createInstanceWithContext(
291cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop") ),
292cdf0e10cSrcweir m_xContext ),
293cdf0e10cSrcweir css::uno::UNO_QUERY );
294cdf0e10cSrcweir
295cdf0e10cSrcweir if ( xDesktop.is() )
296cdf0e10cSrcweir {
297cdf0e10cSrcweir xDesktop->addTerminateListener( css::uno::Reference< css::frame::XTerminateListener >( static_cast< cppu::OWeakObject* >( this ), css::uno::UNO_QUERY ) );
298cdf0e10cSrcweir }
299cdf0e10cSrcweir }
300cdf0e10cSrcweir
~FinalThreadManager()301cdf0e10cSrcweir FinalThreadManager::~FinalThreadManager()
302cdf0e10cSrcweir {
303cdf0e10cSrcweir if ( mpPauseThreadStarting != 0 )
304cdf0e10cSrcweir {
305cdf0e10cSrcweir delete mpPauseThreadStarting;
306cdf0e10cSrcweir mpPauseThreadStarting = 0;
307cdf0e10cSrcweir }
308cdf0e10cSrcweir
309cdf0e10cSrcweir if ( mpTerminateOfficeThread != 0 )
310cdf0e10cSrcweir {
311cdf0e10cSrcweir mpTerminateOfficeThread->StopOfficeTermination(); // thread kills itself.
312cdf0e10cSrcweir mpTerminateOfficeThread = 0;
313cdf0e10cSrcweir }
314cdf0e10cSrcweir
315cdf0e10cSrcweir if ( !maThreads.empty() )
316cdf0e10cSrcweir {
317cdf0e10cSrcweir ASSERT( false, "<FinalThreadManager::~FinalThreadManager()> - still registered jobs are existing -> perform cancellation" );
318cdf0e10cSrcweir cancelAllJobs();
319cdf0e10cSrcweir }
320cdf0e10cSrcweir
321cdf0e10cSrcweir if ( mpCancelJobsThread != 0 )
322cdf0e10cSrcweir {
323cdf0e10cSrcweir if ( !mpCancelJobsThread->allJobsCancelled() )
324cdf0e10cSrcweir {
325cdf0e10cSrcweir ASSERT( false, "<FinalThreadManager::~FinalThreadManager()> - cancellation of registered jobs not yet finished -> wait for its finish" );
326cdf0e10cSrcweir }
327cdf0e10cSrcweir
328cdf0e10cSrcweir mpCancelJobsThread->stopWhenAllJobsCancelled();
329cdf0e10cSrcweir mpCancelJobsThread->join();
330cdf0e10cSrcweir delete mpCancelJobsThread;
331cdf0e10cSrcweir mpCancelJobsThread = 0;
332cdf0e10cSrcweir }
333cdf0e10cSrcweir }
334cdf0e10cSrcweir
335cdf0e10cSrcweir // com.sun.star.uno.XServiceInfo:
getImplementationName()336cdf0e10cSrcweir ::rtl::OUString SAL_CALL FinalThreadManager::getImplementationName() throw (css::uno::RuntimeException)
337cdf0e10cSrcweir {
338cdf0e10cSrcweir return comp_FinalThreadManager::_getImplementationName();
339cdf0e10cSrcweir }
340cdf0e10cSrcweir
supportsService(::rtl::OUString const & serviceName)341cdf0e10cSrcweir ::sal_Bool SAL_CALL FinalThreadManager::supportsService(::rtl::OUString const & serviceName) throw (css::uno::RuntimeException)
342cdf0e10cSrcweir {
343cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > serviceNames = comp_FinalThreadManager::_getSupportedServiceNames();
344cdf0e10cSrcweir for (::sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {
345cdf0e10cSrcweir if (serviceNames[i] == serviceName)
346cdf0e10cSrcweir return sal_True;
347cdf0e10cSrcweir }
348cdf0e10cSrcweir return sal_False;
349cdf0e10cSrcweir }
350cdf0e10cSrcweir
getSupportedServiceNames()351cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > SAL_CALL FinalThreadManager::getSupportedServiceNames() throw (css::uno::RuntimeException)
352cdf0e10cSrcweir {
353cdf0e10cSrcweir return comp_FinalThreadManager::_getSupportedServiceNames();
354cdf0e10cSrcweir }
355cdf0e10cSrcweir
356cdf0e10cSrcweir // ::com::sun::star::util::XJobManager:
registerJob(const css::uno::Reference<css::util::XCancellable> & Job)357cdf0e10cSrcweir void SAL_CALL FinalThreadManager::registerJob(const css::uno::Reference< css::util::XCancellable > & Job) throw (css::uno::RuntimeException)
358cdf0e10cSrcweir {
359cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
360cdf0e10cSrcweir
361cdf0e10cSrcweir maThreads.push_back( Job );
362cdf0e10cSrcweir
363cdf0e10cSrcweir if ( !mbRegisteredAtDesktop )
364cdf0e10cSrcweir {
365cdf0e10cSrcweir registerAsListenerAtDesktop();
366cdf0e10cSrcweir mbRegisteredAtDesktop = true;
367cdf0e10cSrcweir }
368cdf0e10cSrcweir }
369cdf0e10cSrcweir
releaseJob(const css::uno::Reference<css::util::XCancellable> & Job)370cdf0e10cSrcweir void SAL_CALL FinalThreadManager::releaseJob(const css::uno::Reference< css::util::XCancellable > & Job) throw (css::uno::RuntimeException)
371cdf0e10cSrcweir {
372cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
373cdf0e10cSrcweir
374cdf0e10cSrcweir maThreads.remove( Job );
375cdf0e10cSrcweir }
376cdf0e10cSrcweir
cancelAllJobs()377cdf0e10cSrcweir void SAL_CALL FinalThreadManager::cancelAllJobs() throw (css::uno::RuntimeException)
378cdf0e10cSrcweir {
379cdf0e10cSrcweir std::list< css::uno::Reference< css::util::XCancellable > > aThreads;
380cdf0e10cSrcweir {
381cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
382cdf0e10cSrcweir
383cdf0e10cSrcweir aThreads.insert( aThreads.end(), maThreads.begin(), maThreads.end() );
384cdf0e10cSrcweir maThreads.clear();
385cdf0e10cSrcweir }
386cdf0e10cSrcweir
387cdf0e10cSrcweir if ( !aThreads.empty() )
388cdf0e10cSrcweir {
389cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
390cdf0e10cSrcweir
391cdf0e10cSrcweir if ( mpCancelJobsThread == 0 )
392cdf0e10cSrcweir {
393cdf0e10cSrcweir mpCancelJobsThread = new CancelJobsThread( aThreads );;
394cdf0e10cSrcweir if ( !mpCancelJobsThread->create() )
395cdf0e10cSrcweir {
396cdf0e10cSrcweir // error handling
397cdf0e10cSrcweir // ASSERT( false, "<FinalThreadManager::cancelAllJobs()> - thread to cancel jobs can't be setup --> synchron cancellation of jobs" );
398cdf0e10cSrcweir delete mpCancelJobsThread;
399cdf0e10cSrcweir mpCancelJobsThread = 0;
400cdf0e10cSrcweir while ( !aThreads.empty() )
401cdf0e10cSrcweir {
402cdf0e10cSrcweir aThreads.front()->cancel();
403cdf0e10cSrcweir aThreads.pop_front();
404cdf0e10cSrcweir }
405cdf0e10cSrcweir }
406cdf0e10cSrcweir }
407cdf0e10cSrcweir else
408cdf0e10cSrcweir {
409cdf0e10cSrcweir mpCancelJobsThread->addJobs( aThreads );
410cdf0e10cSrcweir }
411cdf0e10cSrcweir }
412cdf0e10cSrcweir }
413cdf0e10cSrcweir
414cdf0e10cSrcweir // ::com::sun::star::frame::XTerminateListener
queryTermination(const css::lang::EventObject &)415cdf0e10cSrcweir void SAL_CALL FinalThreadManager::queryTermination( const css::lang::EventObject& ) throw (css::frame::TerminationVetoException, css::uno::RuntimeException)
416cdf0e10cSrcweir {
417cdf0e10cSrcweir osl::MutexGuard aGuard(maMutex);
418cdf0e10cSrcweir
419cdf0e10cSrcweir cancelAllJobs();
420cdf0e10cSrcweir // Sleep 1 second to give the thread for job cancellation some time.
421cdf0e10cSrcweir // Probably, all started threads have already finished its work.
422cdf0e10cSrcweir if ( mpCancelJobsThread != 0 &&
423cdf0e10cSrcweir !mpCancelJobsThread->allJobsCancelled() )
424cdf0e10cSrcweir {
425cdf0e10cSrcweir TimeValue aSleepTime;
426cdf0e10cSrcweir aSleepTime.Seconds = 1;
427cdf0e10cSrcweir aSleepTime.Nanosec = 0;
428cdf0e10cSrcweir osl_waitThread( &aSleepTime );
429cdf0e10cSrcweir }
430cdf0e10cSrcweir
431cdf0e10cSrcweir if ( mpCancelJobsThread != 0 &&
432cdf0e10cSrcweir !mpCancelJobsThread->allJobsCancelled() )
433cdf0e10cSrcweir {
434cdf0e10cSrcweir if ( mpTerminateOfficeThread != 0 )
435cdf0e10cSrcweir {
436cdf0e10cSrcweir if ( mpTerminateOfficeThread->isRunning() )
437cdf0e10cSrcweir {
438cdf0e10cSrcweir mpTerminateOfficeThread->StopOfficeTermination(); // thread kills itself.
439cdf0e10cSrcweir }
440cdf0e10cSrcweir else
441cdf0e10cSrcweir {
442cdf0e10cSrcweir delete mpTerminateOfficeThread;
443cdf0e10cSrcweir }
444cdf0e10cSrcweir mpTerminateOfficeThread = 0;
445cdf0e10cSrcweir }
446cdf0e10cSrcweir mpTerminateOfficeThread = new TerminateOfficeThread( *mpCancelJobsThread,
447cdf0e10cSrcweir m_xContext );
448cdf0e10cSrcweir if ( !mpTerminateOfficeThread->create() )
449cdf0e10cSrcweir {
450cdf0e10cSrcweir // ASSERT( false, "FinalThreadManager::queryTermination(..) - thread to terminate office can't be started!" );
451cdf0e10cSrcweir delete mpTerminateOfficeThread;
452cdf0e10cSrcweir mpTerminateOfficeThread = 0;
453cdf0e10cSrcweir }
454cdf0e10cSrcweir
455cdf0e10cSrcweir throw css::frame::TerminationVetoException();
456cdf0e10cSrcweir }
457cdf0e10cSrcweir
458cdf0e10cSrcweir mpPauseThreadStarting = new SwPauseThreadStarting();
459cdf0e10cSrcweir
460cdf0e10cSrcweir return;
461cdf0e10cSrcweir }
462cdf0e10cSrcweir
cancelTermination(const css::lang::EventObject &)463cdf0e10cSrcweir void SAL_CALL FinalThreadManager::cancelTermination( const css::lang::EventObject& ) throw (css::uno::RuntimeException)
464cdf0e10cSrcweir {
465cdf0e10cSrcweir if ( mpPauseThreadStarting != 0 )
466cdf0e10cSrcweir {
467cdf0e10cSrcweir delete mpPauseThreadStarting;
468cdf0e10cSrcweir mpPauseThreadStarting = 0;
469cdf0e10cSrcweir }
470cdf0e10cSrcweir
471cdf0e10cSrcweir return;
472cdf0e10cSrcweir }
473cdf0e10cSrcweir
notifyTermination(const css::lang::EventObject &)474cdf0e10cSrcweir void SAL_CALL FinalThreadManager::notifyTermination( const css::lang::EventObject& ) throw (css::uno::RuntimeException)
475cdf0e10cSrcweir {
476cdf0e10cSrcweir if ( mpTerminateOfficeThread != 0 )
477cdf0e10cSrcweir {
478cdf0e10cSrcweir if ( mpTerminateOfficeThread->isRunning() )
479cdf0e10cSrcweir {
480cdf0e10cSrcweir // ASSERT( false, "<FinalThreadManager::notifyTermination()> - office termination thread still running!" );
481cdf0e10cSrcweir mpTerminateOfficeThread->StopOfficeTermination(); // thread kills itself.
482cdf0e10cSrcweir }
483cdf0e10cSrcweir else
484cdf0e10cSrcweir {
485cdf0e10cSrcweir delete mpTerminateOfficeThread;
486cdf0e10cSrcweir }
487cdf0e10cSrcweir mpTerminateOfficeThread = 0;
488cdf0e10cSrcweir }
489cdf0e10cSrcweir
490cdf0e10cSrcweir if ( !maThreads.empty() )
491cdf0e10cSrcweir {
492cdf0e10cSrcweir // ASSERT( false, "<FinalThreadManager::notifyTermination()> - still registered jobs are existing" );
493cdf0e10cSrcweir cancelAllJobs();
494cdf0e10cSrcweir }
495cdf0e10cSrcweir
496cdf0e10cSrcweir if ( mpCancelJobsThread != 0 )
497cdf0e10cSrcweir {
498cdf0e10cSrcweir if ( !mpCancelJobsThread->allJobsCancelled() )
499cdf0e10cSrcweir {
500cdf0e10cSrcweir // ASSERT( false, "<FinalThreadManager::notifyTermination()> - cancellation of registered jobs not yet finished -> wait for its finish" );
501cdf0e10cSrcweir }
502cdf0e10cSrcweir
503cdf0e10cSrcweir mpCancelJobsThread->stopWhenAllJobsCancelled();
504cdf0e10cSrcweir mpCancelJobsThread->join();
505cdf0e10cSrcweir delete mpCancelJobsThread;
506cdf0e10cSrcweir mpCancelJobsThread = 0;
507cdf0e10cSrcweir }
508cdf0e10cSrcweir
509cdf0e10cSrcweir // get reference of this
510cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > aOwnRef( static_cast< cppu::OWeakObject* >( this ));
511cdf0e10cSrcweir // notify <SwThreadJoiner> to release its reference
512cdf0e10cSrcweir SwThreadJoiner::ReleaseThreadJoiner();
513cdf0e10cSrcweir }
514cdf0e10cSrcweir
515cdf0e10cSrcweir // ::com::sun:star::lang::XEventListener (inherited via com::sun::star::frame::XTerminateListener)
disposing(const css::lang::EventObject &)516cdf0e10cSrcweir void SAL_CALL FinalThreadManager::disposing( const css::lang::EventObject& ) throw (css::uno::RuntimeException)
517cdf0e10cSrcweir {
518cdf0e10cSrcweir // nothing to do, because instance doesn't hold any references of observed objects
519cdf0e10cSrcweir }
520cdf0e10cSrcweir
521cdf0e10cSrcweir // component helper namespace
522cdf0e10cSrcweir namespace comp_FinalThreadManager {
523cdf0e10cSrcweir
_getImplementationName()524cdf0e10cSrcweir ::rtl::OUString SAL_CALL _getImplementationName()
525cdf0e10cSrcweir {
526cdf0e10cSrcweir return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
527cdf0e10cSrcweir "com.sun.star.util.comp.FinalThreadManager"));
528cdf0e10cSrcweir }
529cdf0e10cSrcweir
_getSupportedServiceNames()530cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > SAL_CALL _getSupportedServiceNames()
531cdf0e10cSrcweir {
532cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > s(1);
533cdf0e10cSrcweir s[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
534cdf0e10cSrcweir "com.sun.star.util.JobManager"));
535cdf0e10cSrcweir return s;
536cdf0e10cSrcweir }
537cdf0e10cSrcweir
_create(const css::uno::Reference<css::uno::XComponentContext> & context)538cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > SAL_CALL _create(
539cdf0e10cSrcweir const css::uno::Reference< css::uno::XComponentContext > & context)
540cdf0e10cSrcweir SAL_THROW((css::uno::Exception))
541cdf0e10cSrcweir {
542cdf0e10cSrcweir return static_cast< ::cppu::OWeakObject * >(new FinalThreadManager(context));
543cdf0e10cSrcweir }
544cdf0e10cSrcweir
545cdf0e10cSrcweir } // closing component helper namespace
546