nss: upgrade to release 3.73
[LibreOffice.git] / framework / source / jobs / job.cxx
blob4cb9c5bb0ce137b3b3d301b6c552ff23fbbe2a09
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <jobs/job.hxx>
21 #include <jobs/jobresult.hxx>
23 #include <com/sun/star/frame/Desktop.hpp>
24 #include <com/sun/star/frame/TerminationVetoException.hpp>
25 #include <com/sun/star/task/XJob.hpp>
26 #include <com/sun/star/task/XAsyncJob.hpp>
27 #include <com/sun/star/util/CloseVetoException.hpp>
28 #include <com/sun/star/util/XCloseBroadcaster.hpp>
29 #include <com/sun/star/util/XCloseable.hpp>
30 #include <com/sun/star/lang/DisposedException.hpp>
32 #include <comphelper/sequence.hxx>
33 #include <sal/log.hxx>
34 #include <tools/diagnose_ex.h>
35 #include <vcl/svapp.hxx>
37 namespace framework{
39 /**
40 @short standard ctor
41 @descr It initialize this new instance. But it set some generic parameters here only.
42 Specialized information (e.g. the alias or service name ofthis job) will be set
43 later using the method setJobData().
45 @param xContext
46 reference to the uno service manager
48 @param xFrame
49 reference to the frame, in which environment we run
50 (May be null!)
52 Job::Job( /*IN*/ const css::uno::Reference< css::uno::XComponentContext >& xContext ,
53 /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame )
54 : m_aJobCfg (xContext )
55 , m_xContext (xContext )
56 , m_xFrame (xFrame )
57 , m_bListenOnDesktop (false )
58 , m_bListenOnFrame (false )
59 , m_bListenOnModel (false )
60 , m_bPendingCloseFrame (false )
61 , m_bPendingCloseModel (false )
62 , m_eRunState (E_NEW )
66 /**
67 @short standard ctor
68 @descr It initialize this new instance. But it set some generic parameters here only.
69 Specialized information (e.g. the alias or service name ofthis job) will be set
70 later using the method setJobData().
72 @param xContext
73 reference to the uno service manager
75 @param xModel
76 reference to the model, in which environment we run
77 (May be null!)
79 Job::Job( /*IN*/ const css::uno::Reference< css::uno::XComponentContext >& xContext ,
80 /*IN*/ const css::uno::Reference< css::frame::XModel >& xModel )
81 : m_aJobCfg (xContext )
82 , m_xContext (xContext )
83 , m_xModel (xModel )
84 , m_bListenOnDesktop (false )
85 , m_bListenOnFrame (false )
86 , m_bListenOnModel (false )
87 , m_bPendingCloseFrame (false )
88 , m_bPendingCloseModel (false )
89 , m_eRunState (E_NEW )
93 /**
94 @short superfluous!
95 @descr Releasing of memory and reference must be done inside die() call.
96 Otherwise it's a bug.
98 Job::~Job()
103 @short set (or delete) a listener for sending dispatch result events
104 @descr Because this object is used in a wrapped mode ... the original listener
105 for such events can't be registered here directly. Because the
106 listener expect to get the original object given as source of the event.
107 That's why we get this source here too, to fake(!) it at sending time!
109 @param xListener
110 the original listener for dispatch result events
112 @param xSourceFake
113 our user, which got the registration request for this listener
115 void Job::setDispatchResultFake( /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ,
116 /*IN*/ const css::uno::Reference< css::uno::XInterface >& xSourceFake )
118 SolarMutexGuard g;
120 // reject dangerous calls
121 if (m_eRunState != E_NEW)
123 SAL_INFO("fwk", "Job::setJobData(): job may still running or already finished");
124 return;
127 m_xResultListener = xListener;
128 m_xResultSourceFake = xSourceFake;
131 void Job::setJobData( const JobData& aData )
133 SolarMutexGuard g;
135 // reject dangerous calls
136 if (m_eRunState != E_NEW)
138 SAL_INFO("fwk", "Job::setJobData(): job may still running or already finished");
139 return;
142 m_aJobCfg = aData;
146 @short runs the job
147 @descr It doesn't matter, if the job is an asynchronous or
148 synchronous one. This method returns only if it was finished
149 or cancelled.
151 @param lDynamicArgs
152 optional arguments for job execution
153 In case the represented job is a configured one (which uses static
154 arguments too) all information will be merged!
156 void Job::execute( /*IN*/ const css::uno::Sequence< css::beans::NamedValue >& lDynamicArgs )
158 /* SAFE { */
159 SolarMutexResettableGuard aWriteLock;
161 // reject dangerous calls
162 if (m_eRunState != E_NEW)
164 SAL_INFO("fwk", "Job::execute(): job may still running or already finished");
165 return;
168 // create the environment and mark this job as running ...
169 m_eRunState = E_RUNNING;
170 impl_startListening();
172 css::uno::Reference< css::task::XAsyncJob > xAJob;
173 css::uno::Reference< css::task::XJob > xSJob;
174 css::uno::Sequence< css::beans::NamedValue > lJobArgs = impl_generateJobArgs(lDynamicArgs);
176 // It's necessary to hold us self alive!
177 // Otherwise we might die by ref count ...
178 css::uno::Reference< css::task::XJobListener > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
182 // create the job
183 // We must check for the supported interface on demand!
184 // But we prefer the synchronous one ...
185 m_xJob = m_xContext->getServiceManager()->createInstanceWithContext(m_aJobCfg.getService(), m_xContext);
186 xSJob.set(m_xJob, css::uno::UNO_QUERY);
187 if (!xSJob.is())
188 xAJob.set(m_xJob, css::uno::UNO_QUERY);
190 // execute it asynchronous
191 if (xAJob.is())
193 m_aAsyncWait.reset();
194 aWriteLock.clear();
195 /* } SAFE */
196 xAJob->executeAsync(lJobArgs, xThis);
197 // wait for finishing this job - so this method
198 // does the same for synchronous and asynchronous jobs!
199 m_aAsyncWait.wait();
200 aWriteLock.reset();
201 /* SAFE { */
202 // Note: Result handling was already done inside the callback!
204 // execute it synchron
205 else if (xSJob.is())
207 aWriteLock.clear();
208 /* } SAFE */
209 css::uno::Any aResult = xSJob->execute(lJobArgs);
210 aWriteLock.reset();
211 /* SAFE { */
212 impl_reactForJobResult(aResult);
215 #if OSL_DEBUG_LEVEL > 0
216 catch(const css::uno::Exception&)
218 TOOLS_INFO_EXCEPTION("fwk", "Job::execute(): Got exception during job execution");
220 #else
221 catch(const css::uno::Exception&)
223 #endif
225 // deinitialize the environment and mark this job as finished...
226 // but don't overwrite any information about STOPPED or might DISPOSED jobs!
227 impl_stopListening();
228 if (m_eRunState == E_RUNNING)
229 m_eRunState = E_STOPPED_OR_FINISHED;
231 // If we got a close request from our frame or model...
232 // but we disagreed with that by throwing a veto exception...
233 // and got the ownership...
234 // we have to close the resource frame or model now -
235 // and to disable ourself!
236 if (m_bPendingCloseFrame)
238 m_bPendingCloseFrame = false;
239 css::uno::Reference< css::util::XCloseable > xClose(m_xFrame, css::uno::UNO_QUERY);
240 if (xClose.is())
244 xClose->close(true);
246 catch(const css::util::CloseVetoException&) {}
250 if (m_bPendingCloseModel)
252 m_bPendingCloseModel = false;
253 css::uno::Reference< css::util::XCloseable > xClose(m_xModel, css::uno::UNO_QUERY);
254 if (xClose.is())
258 xClose->close(true);
260 catch(const css::util::CloseVetoException&) {}
264 aWriteLock.clear();
265 /* SAFE { */
267 // release this instance ...
268 die();
272 @short kill this job
273 @descr It doesn't matter if this request is called from inside or
274 from outside. We release our internal structures and stop
275 every activity. After doing so - this instance will not be
276 usable any longer! Of course we try to handle further requests
277 carefully. Maybe someone else holds a reference to us ...
279 void Job::die()
281 SolarMutexGuard g;
283 impl_stopListening();
285 if (m_eRunState != E_DISPOSED)
289 css::uno::Reference< css::lang::XComponent > xDispose(m_xJob, css::uno::UNO_QUERY);
290 if (xDispose.is())
292 xDispose->dispose();
293 m_eRunState = E_DISPOSED;
296 catch(const css::lang::DisposedException&)
298 m_eRunState = E_DISPOSED;
302 m_xJob.clear();
303 m_xFrame.clear();
304 m_xModel.clear();
305 m_xDesktop.clear();
306 m_xResultListener.clear();
307 m_xResultSourceFake.clear();
308 m_bPendingCloseFrame = false;
309 m_bPendingCloseModel = false;
313 @short generates list of arguments for job execute
314 @descr There exist a set of information, which can be needed by a job.
315 a) it's static configuration data (Equals for all jobs. )
316 b) it's specific configuration data (Different for every job.)
317 c) some environment values (e.g. the frame, for which this job was started)
318 d) any other dynamic data (e.g. parameters of a dispatch() request)
319 We collect all this information and generate one list which include all others.
321 @param lDynamicArgs
322 list of dynamic arguments (given by a corresponding dispatch() call)
323 Can be empty too.
325 @return A list which includes all mentioned sub lists.
327 css::uno::Sequence< css::beans::NamedValue > Job::impl_generateJobArgs( /*IN*/ const css::uno::Sequence< css::beans::NamedValue >& lDynamicArgs )
329 css::uno::Sequence< css::beans::NamedValue > lAllArgs;
331 /* SAFE { */
332 SolarMutexClearableGuard aReadLock;
334 // the real structure of the returned list depends from the environment of this job!
335 JobData::EMode eMode = m_aJobCfg.getMode();
337 // Create list of environment variables. This list must be part of the
338 // returned structure every time... but some of its members are optional!
339 css::uno::Sequence< css::beans::NamedValue > lEnvArgs(1);
340 lEnvArgs[0].Name = "EnvType";
341 lEnvArgs[0].Value <<= m_aJobCfg.getEnvironmentDescriptor();
343 if (m_xFrame.is())
345 sal_Int32 c = lEnvArgs.getLength();
346 lEnvArgs.realloc(c+1);
347 lEnvArgs[c].Name = "Frame";
348 lEnvArgs[c].Value <<= m_xFrame;
350 if (m_xModel.is())
352 sal_Int32 c = lEnvArgs.getLength();
353 lEnvArgs.realloc(c+1);
354 lEnvArgs[c].Name = "Model";
355 lEnvArgs[c].Value <<= m_xModel;
357 if (eMode==JobData::E_EVENT)
359 sal_Int32 c = lEnvArgs.getLength();
360 lEnvArgs.realloc(c+1);
361 lEnvArgs[c].Name = "EventName";
362 lEnvArgs[c].Value <<= m_aJobCfg.getEvent();
365 // get the configuration data from the job data container ... if possible
366 // Means: if this job has any configuration data. Note: only really
367 // filled lists will be set to the return structure at the end of this method.
368 css::uno::Sequence< css::beans::NamedValue > lConfigArgs;
369 std::vector< css::beans::NamedValue > lJobConfigArgs;
370 if (eMode==JobData::E_ALIAS || eMode==JobData::E_EVENT)
372 lConfigArgs = m_aJobCfg.getConfig();
373 lJobConfigArgs = m_aJobCfg.getJobConfig();
376 aReadLock.clear();
377 /* } SAFE */
379 // Add all valid (not empty) lists to the return list
380 if (lConfigArgs.hasElements())
382 sal_Int32 nLength = lAllArgs.getLength();
383 lAllArgs.realloc(nLength+1);
384 lAllArgs[nLength].Name = "Config";
385 lAllArgs[nLength].Value <<= lConfigArgs;
387 if (!lJobConfigArgs.empty())
389 sal_Int32 nLength = lAllArgs.getLength();
390 lAllArgs.realloc(nLength+1);
391 lAllArgs[nLength].Name = "JobConfig";
392 lAllArgs[nLength].Value <<= comphelper::containerToSequence(lJobConfigArgs);
394 if (lEnvArgs.hasElements())
396 sal_Int32 nLength = lAllArgs.getLength();
397 lAllArgs.realloc(nLength+1);
398 lAllArgs[nLength].Name = "Environment";
399 lAllArgs[nLength].Value <<= lEnvArgs;
401 if (lDynamicArgs.hasElements())
403 sal_Int32 nLength = lAllArgs.getLength();
404 lAllArgs.realloc(nLength+1);
405 lAllArgs[nLength].Name = "DynamicData";
406 lAllArgs[nLength].Value <<= lDynamicArgs;
409 return lAllArgs;
413 @short analyze the given job result and change the job configuration
414 @descr Note: Some results can be handled only, if this job has a valid configuration!
415 For "not configured jobs" (means pure services) they can be ignored.
416 But these cases are handled by our JobData member. We can call it every time.
417 It does the right things automatically. E.g. if the job has no configuration ...
418 it does nothing during setJobConfig()!
420 @param aResult
421 the job result for analyzing
423 void Job::impl_reactForJobResult( /*IN*/ const css::uno::Any& aResult )
425 SolarMutexGuard g;
427 // analyze the result set ...
428 JobResult aAnalyzedResult(aResult);
430 // some of the following operations will be supported for different environments
431 // or different type of jobs only.
432 JobData::EEnvironment eEnvironment = m_aJobCfg.getEnvironment();
434 // write back the job specific configuration data ...
435 // If the environment allow it and if this job has a configuration!
436 if (
437 (m_aJobCfg.hasConfig() ) &&
438 (aAnalyzedResult.existPart(JobResult::E_ARGUMENTS))
441 m_aJobCfg.setJobConfig(aAnalyzedResult.getArguments());
444 // disable a job for further executions.
445 // Note: this option is available inside the environment EXECUTOR only
446 if (
447 // (eEnvironment == JobData::E_EXECUTION ) &&
448 (m_aJobCfg.hasConfig() ) &&
449 (aAnalyzedResult.existPart(JobResult::E_DEACTIVATE))
452 m_aJobCfg.disableJob();
455 // notify any interested listener with the may given result state.
456 // Note: this option is available inside the environment DISPATCH only
457 if (
458 (eEnvironment == JobData::E_DISPATCH ) &&
459 (m_xResultListener.is() ) &&
460 (aAnalyzedResult.existPart(JobResult::E_DISPATCHRESULT))
463 // Attention: Because the listener expect that the original object send this event ...
464 // and we nor the job are the right ones ...
465 // our user has set itself before. So we can fake this source address!
466 css::frame::DispatchResultEvent aEvent = aAnalyzedResult.getDispatchResult();
467 aEvent.Source = m_xResultSourceFake;
468 m_xResultListener->dispatchFinished(aEvent);
473 @short starts listening for office shutdown and closing of our
474 given target frame (if it's a valid reference)
475 @descr We will register ourself as terminate listener
476 at the global desktop instance. That will hold us
477 alive and additional we get the information, if the
478 office wish to shutdown. If then an internal job
479 is running we will have the chance to suppress that
480 by throwing a veto exception. If our internal wrapped
481 job finished his work, we can release this listener
482 connection.
484 Further we are listener for closing of the (possible valid)
485 given frame. We must be sure, that this resource won't be gone
486 if our internal job is still running.
488 void Job::impl_startListening()
490 SolarMutexGuard g;
492 // listening for office shutdown
493 if (!m_xDesktop.is() && !m_bListenOnDesktop)
497 m_xDesktop = css::frame::Desktop::create( m_xContext );
498 css::uno::Reference< css::frame::XTerminateListener > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
499 m_xDesktop->addTerminateListener(xThis);
500 m_bListenOnDesktop = true;
502 catch(const css::uno::Exception&)
504 m_xDesktop.clear();
508 // listening for frame closing
509 if (m_xFrame.is() && !m_bListenOnFrame)
513 css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xFrame , css::uno::UNO_QUERY);
514 css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
515 if (xCloseable.is())
517 xCloseable->addCloseListener(xThis);
518 m_bListenOnFrame = true;
521 catch(const css::uno::Exception&)
523 m_bListenOnFrame = false;
527 // listening for model closing
528 if (!m_xModel.is() || m_bListenOnModel)
529 return;
533 css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xModel , css::uno::UNO_QUERY);
534 css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
535 if (xCloseable.is())
537 xCloseable->addCloseListener(xThis);
538 m_bListenOnModel = true;
541 catch(const css::uno::Exception&)
543 m_bListenOnModel = false;
548 @short release listener connection for office shutdown
549 @descr see description of impl_startListening()
551 void Job::impl_stopListening()
553 SolarMutexGuard g;
555 // stop listening for office shutdown
556 if (m_xDesktop.is() && m_bListenOnDesktop)
560 css::uno::Reference< css::frame::XTerminateListener > xThis(static_cast< ::cppu::OWeakObject* >(this) , css::uno::UNO_QUERY);
561 m_xDesktop->removeTerminateListener(xThis);
562 m_xDesktop.clear();
563 m_bListenOnDesktop = false;
565 catch(const css::uno::Exception&)
570 // stop listening for frame closing
571 if (m_xFrame.is() && m_bListenOnFrame)
575 css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xFrame , css::uno::UNO_QUERY);
576 css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
577 if (xCloseable.is())
579 xCloseable->removeCloseListener(xThis);
580 m_bListenOnFrame = false;
583 catch(const css::uno::Exception&)
588 // stop listening for model closing
589 if (!(m_xModel.is() && m_bListenOnModel))
590 return;
594 css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xModel , css::uno::UNO_QUERY);
595 css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
596 if (xCloseable.is())
598 xCloseable->removeCloseListener(xThis);
599 m_bListenOnModel = false;
602 catch(const css::uno::Exception&)
608 @short callback from any asynchronous executed job
610 @descr Our execute() method waits for this callback.
611 We have to react for the possible results here,
612 to kill the running job and disable the blocked condition
613 so execute() can be finished too.
615 @param xJob
616 the job, which was running and inform us now
618 @param aResult
619 its results
621 void SAL_CALL Job::jobFinished( /*IN*/ const css::uno::Reference< css::task::XAsyncJob >& xJob ,
622 /*IN*/ const css::uno::Any& aResult )
624 SolarMutexGuard g;
626 // It's necessary to check this.
627 // May this job was cancelled by any other reason
628 // some milliseconds before. :-)
629 if (m_xJob.is() && m_xJob==xJob)
631 // react for his results
632 // (means enable/disable it for further requests
633 // or save arguments or notify listener ...)
634 impl_reactForJobResult(aResult);
636 // Let the job die!
637 m_xJob.clear();
640 // And let the start method "execute()" finishing it's job.
641 // But do it every time. So any outside blocking code can finish
642 // his work too.
643 m_aAsyncWait.set();
647 @short prevent internal wrapped job against office termination
648 @descr This event is broadcasted by the desktop instance and ask for an office termination.
649 If the internal wrapped job is still in progress, we disagree with that by throwing the
650 right veto exception. If not - we agree. But then we must be aware, that another event
651 notifyTermination() can follow. Then we have no chance to do the same. Then we have to
652 accept that and stop our work instandly.
654 @param aEvent
655 describes the broadcaster and must be the desktop instance
657 @throw TerminateVetoException
658 if our internal wrapped job is still running.
660 void SAL_CALL Job::queryTermination( /*IN*/ const css::lang::EventObject& )
662 SolarMutexGuard g;
664 // Otherwise try to close() it
665 css::uno::Reference< css::util::XCloseable > xClose(m_xJob, css::uno::UNO_QUERY);
666 if (xClose.is())
670 xClose->close(false);
671 m_eRunState = E_STOPPED_OR_FINISHED;
673 catch(const css::util::CloseVetoException&) {}
676 if (m_eRunState != E_STOPPED_OR_FINISHED)
678 css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
679 throw css::frame::TerminationVetoException("job still in progress", xThis);
684 @short inform us about office termination
685 @descr Instead of the method queryTermination(), here is no chance to disagree with that.
686 We have to accept it and cancel all current processes inside.
687 It can occur only, if job was not already started if queryTermination() was called here.
688 Then we had not thrown a veto exception. But now we must agree with this situation and break
689 all our internal processes. It's not a good idea to mark this instance as non startable any longer
690 inside queryTermination() if no job was running too. Because that would disable this job and may
691 the office does not really shutdown, because another listener has thrown the suitable exception.
693 @param aEvent
694 describes the broadcaster and must be the desktop instance
696 void SAL_CALL Job::notifyTermination( /*IN*/ const css::lang::EventObject& )
698 die();
699 // Do nothing else here. Our internal resources was released ...
703 @short prevent internal wrapped job against frame closing
704 @descr This event is broadcasted by the frame instance and ask for closing.
705 If the internal wrapped job is still in progress, we disagree with that by throwing the
706 right veto exception. If not - we agree. But then we must be aware, that another event
707 notifyClosing() can follow. Then we have no chance to do the same. Then we have to
708 accept that and stop our work instandly.
710 @param aEvent
711 describes the broadcaster and must be the frame instance
713 @param bGetsOwnership
714 If it's set to <sal_True> and we throw the right veto exception, we have to close this frame later
715 if our internal processes will be finished. If it's set to <FALSE/> we can ignore it.
717 @throw CloseVetoException
718 if our internal wrapped job is still running.
720 void SAL_CALL Job::queryClosing( const css::lang::EventObject& aEvent ,
721 sal_Bool bGetsOwnership )
723 SolarMutexGuard g;
725 // do nothing, if no internal job is still running ...
726 // The frame or model can be closed then successfully.
727 if (m_eRunState != E_RUNNING)
728 return;
730 // try close() first at the job.
731 // The job can agree or disagree with this request.
732 css::uno::Reference< css::util::XCloseable > xClose(m_xJob, css::uno::UNO_QUERY);
733 if (xClose.is())
735 xClose->close(bGetsOwnership);
736 // Here we can say: "this job was stopped successfully". Because
737 // no veto exception was thrown!
738 m_eRunState = E_STOPPED_OR_FINISHED;
739 return;
742 // try dispose() then
743 // Here the job has no chance for a veto.
744 // But we must be aware of an "already disposed exception"...
747 css::uno::Reference< css::lang::XComponent > xDispose(m_xJob, css::uno::UNO_QUERY);
748 if (xDispose.is())
750 xDispose->dispose();
751 m_eRunState = E_DISPOSED;
754 catch(const css::lang::DisposedException&)
756 // the job was already disposed by any other mechanism !?
757 // But it's not interesting for us. For us this job is stopped now.
758 m_eRunState = E_DISPOSED;
761 if (m_eRunState != E_DISPOSED)
763 // analyze event source - to find out, which resource called queryClosing() at this
764 // job wrapper. We must bind a "pending close" request to this resource.
765 // Closing of the corresponding resource will be done if our internal job finish it's work.
766 m_bPendingCloseFrame = (m_xFrame.is() && aEvent.Source == m_xFrame);
767 m_bPendingCloseModel = (m_xModel.is() && aEvent.Source == m_xModel);
769 // throw suitable veto exception - because the internal job could not be cancelled.
770 css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
771 throw css::util::CloseVetoException("job still in progress", xThis);
774 // No veto ...
775 // But don't call die() here or free our internal member.
776 // This must be done inside notifyClosing() only. Otherwise the
777 // might stopped job has no chance to return its results or
778 // call us back. We must give him the chance to finish it's work successfully.
782 @short inform us about frame closing
783 @descr Instead of the method queryClosing(), here is no chance to disagree with that.
784 We have to accept it and cancel all current processes inside.
786 @param aEvent
787 describes the broadcaster and must be the frame or model instance we know
789 void SAL_CALL Job::notifyClosing( const css::lang::EventObject& )
791 die();
792 // Do nothing else here. Our internal resources was released ...
796 @short shouldn't be called normally
797 @descr But it doesn't matter, who called it. We have to kill our internal
798 running processes hardly.
800 @param aEvent
801 describe the broadcaster
803 void SAL_CALL Job::disposing( const css::lang::EventObject& aEvent )
805 /* SAFE { */
807 SolarMutexGuard aWriteLock;
809 if (m_xDesktop.is() && aEvent.Source == m_xDesktop)
811 m_xDesktop.clear();
812 m_bListenOnDesktop = false;
814 else if (m_xFrame.is() && aEvent.Source == m_xFrame)
816 m_xFrame.clear();
817 m_bListenOnFrame = false;
819 else if (m_xModel.is() && aEvent.Source == m_xModel)
821 m_xModel.clear();
822 m_bListenOnModel = false;
825 /* } SAFE */
827 die();
828 // Do nothing else here. Our internal resources was released ...
831 } // namespace framework
833 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */