1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_framework.hxx" 26 27 //----------------------------------------------- 28 // my own includes 29 30 #include <algorithm> 31 #include <helper/statusindicatorfactory.hxx> 32 #include <helper/statusindicator.hxx> 33 #include <helper/vclstatusindicator.hxx> 34 #include <threadhelp/writeguard.hxx> 35 #include <threadhelp/readguard.hxx> 36 #include <services.h> 37 #include <properties.h> 38 39 //----------------------------------------------- 40 // interface includes 41 #include <com/sun/star/awt/Rectangle.hpp> 42 43 #ifndef _COM_SUN_STAR_AWT_XCONTROLS_HPP_ 44 #include <com/sun/star/awt/XControl.hpp> 45 #endif 46 #include <com/sun/star/awt/XLayoutConstrains.hpp> 47 #include <com/sun/star/awt/DeviceInfo.hpp> 48 #include <com/sun/star/awt/PosSize.hpp> 49 #include <com/sun/star/awt/WindowAttribute.hpp> 50 #include <com/sun/star/awt/XTopWindow.hpp> 51 #include <com/sun/star/awt/XWindow2.hpp> 52 #include <com/sun/star/beans/XPropertySet.hpp> 53 #include <com/sun/star/frame/XLayoutManager.hpp> 54 55 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ 56 #include <toolkit/unohlp.hxx> 57 #endif 58 59 //----------------------------------------------- 60 // includes of other projects 61 #include <comphelper/sequenceashashmap.hxx> 62 #include <comphelper/mediadescriptor.hxx> 63 #include <comphelper/configurationhelper.hxx> 64 #include <vcl/svapp.hxx> 65 #include <vos/mutex.hxx> 66 67 //----------------------------------------------- 68 // namespace 69 70 namespace framework{ 71 72 //----------------------------------------------- 73 // definitions 74 75 sal_Int32 StatusIndicatorFactory::m_nInReschedule = 0; /// static counter for rescheduling 76 static ::rtl::OUString PROGRESS_RESOURCE = ::rtl::OUString::createFromAscii("private:resource/progressbar/progressbar"); 77 78 //----------------------------------------------- 79 DEFINE_XINTERFACE_5(StatusIndicatorFactory , 80 OWeakObject , 81 DIRECT_INTERFACE(css::lang::XTypeProvider ), 82 DIRECT_INTERFACE(css::lang::XServiceInfo ), 83 DIRECT_INTERFACE(css::lang::XInitialization ), 84 DIRECT_INTERFACE(css::task::XStatusIndicatorFactory), 85 DIRECT_INTERFACE(css::util::XUpdatable )) 86 87 DEFINE_XTYPEPROVIDER_5(StatusIndicatorFactory , 88 css::lang::XTypeProvider , 89 css::lang::XServiceInfo , 90 css::lang::XInitialization , 91 css::task::XStatusIndicatorFactory, 92 css::util::XUpdatable ) 93 94 DEFINE_XSERVICEINFO_MULTISERVICE(StatusIndicatorFactory , 95 ::cppu::OWeakObject , 96 SERVICENAME_STATUSINDICATORFACTORY , 97 IMPLEMENTATIONNAME_STATUSINDICATORFACTORY) 98 99 DEFINE_INIT_SERVICE(StatusIndicatorFactory, 100 { 101 /*Attention 102 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance() 103 to create a new instance of this class by our own supported service factory. 104 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations! 105 */ 106 } 107 ) 108 109 //----------------------------------------------- 110 StatusIndicatorFactory::StatusIndicatorFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) 111 : ThreadHelpBase ( ) 112 , ::cppu::OWeakObject ( ) 113 , m_xSMGR (xSMGR ) 114 , m_pWakeUp (0 ) 115 , m_bAllowReschedule (sal_False) 116 , m_bAllowParentShow (sal_False) 117 , m_bDisableReschedule(sal_False) 118 { 119 } 120 121 //----------------------------------------------- 122 StatusIndicatorFactory::~StatusIndicatorFactory() 123 { 124 impl_stopWakeUpThread(); 125 } 126 127 //----------------------------------------------- 128 void SAL_CALL StatusIndicatorFactory::initialize(const css::uno::Sequence< css::uno::Any >& lArguments) 129 throw(css::uno::Exception , 130 css::uno::RuntimeException) 131 { 132 ::comphelper::SequenceAsHashMap lArgs(lArguments); 133 134 // SAFE -> ---------------------------------- 135 WriteGuard aWriteLock(m_aLock); 136 137 m_xFrame = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_FRAME , css::uno::Reference< css::frame::XFrame >()); 138 m_xPluggWindow = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_WINDOW , css::uno::Reference< css::awt::XWindow >() ); 139 m_bAllowParentShow = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_ALLOWPARENTSHOW , (sal_Bool)sal_False ); 140 m_bDisableReschedule = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_DISABLERESCHEDULE, (sal_Bool)sal_False ); 141 142 aWriteLock.unlock(); 143 // <- SAFE ---------------------------------- 144 145 impl_createProgress(); 146 } 147 148 //----------------------------------------------- 149 css::uno::Reference< css::task::XStatusIndicator > SAL_CALL StatusIndicatorFactory::createStatusIndicator() 150 throw(css::uno::RuntimeException) 151 { 152 StatusIndicator* pIndicator = new StatusIndicator(this); 153 css::uno::Reference< css::task::XStatusIndicator > xIndicator(static_cast< ::cppu::OWeakObject* >(pIndicator), css::uno::UNO_QUERY_THROW); 154 155 return xIndicator; 156 } 157 158 //----------------------------------------------- 159 void SAL_CALL StatusIndicatorFactory::update() 160 throw(css::uno::RuntimeException) 161 { 162 // SAFE -> ---------------------------------- 163 WriteGuard aWriteLock(m_aLock); 164 m_bAllowReschedule = sal_True; 165 aWriteLock.unlock(); 166 // <- SAFE ---------------------------------- 167 } 168 169 //----------------------------------------------- 170 void StatusIndicatorFactory::start(const css::uno::Reference< css::task::XStatusIndicator >& xChild, 171 const ::rtl::OUString& sText , 172 sal_Int32 nRange) 173 { 174 // SAFE -> ---------------------------------- 175 WriteGuard aWriteLock(m_aLock); 176 177 // create new info structure for this child or move it to the front of our stack 178 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); 179 if (pItem != m_aStack.end()) 180 m_aStack.erase(pItem); 181 IndicatorInfo aInfo(xChild, sText, nRange); 182 m_aStack.push_back (aInfo ); 183 184 m_xActiveChild = xChild; 185 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; 186 187 aWriteLock.unlock(); 188 // <- SAFE ---------------------------------- 189 190 implts_makeParentVisibleIfAllowed(); 191 192 if (xProgress.is()) 193 xProgress->start(sText, nRange); 194 195 impl_startWakeUpThread(); 196 impl_reschedule(sal_True); 197 } 198 199 //----------------------------------------------- 200 void StatusIndicatorFactory::reset(const css::uno::Reference< css::task::XStatusIndicator >& xChild) 201 { 202 // SAFE -> ---------------------------------- 203 ReadGuard aReadLock(m_aLock); 204 205 // reset the internal info structure related to this child 206 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); 207 if (pItem != m_aStack.end()) 208 { 209 pItem->m_nValue = 0; 210 pItem->m_sText = ::rtl::OUString(); 211 } 212 213 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; 214 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; 215 216 aReadLock.unlock(); 217 // <- SAFE ---------------------------------- 218 219 // not the top most child => dont change UI 220 // But dont forget Reschedule! 221 if ( 222 (xChild == xActive) && 223 (xProgress.is() ) 224 ) 225 xProgress->reset(); 226 227 impl_reschedule(sal_True); 228 } 229 230 //----------------------------------------------- 231 void StatusIndicatorFactory::end(const css::uno::Reference< css::task::XStatusIndicator >& xChild) 232 { 233 // SAFE -> ---------------------------------- 234 WriteGuard aWriteLock(m_aLock); 235 236 // remove this child from our stack 237 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); 238 if (pItem != m_aStack.end()) 239 m_aStack.erase(pItem); 240 241 // activate next child ... or finish the progress if there is no further one. 242 m_xActiveChild.clear(); 243 ::rtl::OUString sText; 244 sal_Int32 nValue = 0; 245 IndicatorStack::reverse_iterator pNext = m_aStack.rbegin(); 246 if (pNext != m_aStack.rend()) 247 { 248 m_xActiveChild = pNext->m_xIndicator; 249 sText = pNext->m_sText; 250 nValue = pNext->m_nValue; 251 } 252 253 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; 254 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; 255 256 aWriteLock.unlock(); 257 // <- SAFE ---------------------------------- 258 259 if (xActive.is()) 260 { 261 // There is at least one further child indicator. 262 // Actualize our progress, so it shows these values from now. 263 if (xProgress.is()) 264 { 265 xProgress->setText (sText ); 266 xProgress->setValue(nValue); 267 } 268 } 269 else 270 { 271 // Our stack is empty. No further child exists. 272 // Se we must "end" our progress really 273 if (xProgress.is()) 274 xProgress->end(); 275 // Now hide the progress bar again. 276 impl_hideProgress(); 277 278 impl_stopWakeUpThread(); 279 } 280 281 impl_reschedule(sal_True); 282 } 283 284 //----------------------------------------------- 285 void StatusIndicatorFactory::setText(const css::uno::Reference< css::task::XStatusIndicator >& xChild, 286 const ::rtl::OUString& sText ) 287 { 288 // SAFE -> ---------------------------------- 289 WriteGuard aWriteLock(m_aLock); 290 291 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); 292 if (pItem != m_aStack.end()) 293 pItem->m_sText = sText; 294 295 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; 296 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; 297 298 aWriteLock.unlock(); 299 // SAFE -> ---------------------------------- 300 301 // paint only the top most indicator 302 // but dont forget to Reschedule! 303 if ( 304 (xChild == xActive) && 305 (xProgress.is() ) 306 ) 307 { 308 xProgress->setText(sText); 309 } 310 311 impl_reschedule(sal_True); 312 } 313 314 //----------------------------------------------- 315 void StatusIndicatorFactory::setValue( const css::uno::Reference< css::task::XStatusIndicator >& xChild , 316 sal_Int32 nValue ) 317 { 318 // SAFE -> ---------------------------------- 319 WriteGuard aWriteLock(m_aLock); 320 321 sal_Int32 nOldValue = 0; 322 IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); 323 if (pItem != m_aStack.end()) 324 { 325 nOldValue = pItem->m_nValue; 326 pItem->m_nValue = nValue; 327 } 328 329 css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; 330 css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; 331 332 aWriteLock.unlock(); 333 // SAFE -> ---------------------------------- 334 335 if ( 336 (xChild == xActive) && 337 (nOldValue != nValue ) && 338 (xProgress.is() ) 339 ) 340 { 341 xProgress->setValue(nValue); 342 } 343 344 impl_reschedule(sal_False); 345 } 346 347 //----------------------------------------------- 348 void StatusIndicatorFactory::implts_makeParentVisibleIfAllowed() 349 { 350 // SAFE -> ---------------------------------- 351 ReadGuard aReadLock(m_aLock); 352 353 if (!m_bAllowParentShow) 354 return; 355 356 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY); 357 css::uno::Reference< css::awt::XWindow > xPluggWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY); 358 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY); 359 360 aReadLock.unlock(); 361 // <- SAFE ---------------------------------- 362 363 css::uno::Reference< css::awt::XWindow > xParentWindow; 364 if (xFrame.is()) 365 xParentWindow = xFrame->getContainerWindow(); 366 else 367 xParentWindow = xPluggWindow; 368 369 // dont disturb user in case he put the loading document into the background! 370 // Suppress any setVisible() or toFront() call in case the initial show was 371 // already made. 372 css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xParentWindow, css::uno::UNO_QUERY); 373 sal_Bool bIsVisible = sal_False; 374 if (xVisibleCheck.is()) 375 bIsVisible = xVisibleCheck->isVisible(); 376 377 if (bIsVisible) 378 { 379 impl_showProgress(); 380 return; 381 } 382 383 // Check if the layout manager has been set to invisible state. It this case we are also 384 // not allowed to set the frame visible! 385 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY); 386 if (xPropSet.is()) 387 { 388 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager; 389 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager; 390 if (xLayoutManager.is()) 391 { 392 if ( !xLayoutManager->isVisible() ) 393 return; 394 } 395 } 396 397 // Ok the window should be made visible ... because it isn't currently visible. 398 // BUT ..! 399 // We need a Hack for our applications: They get her progress from the frame directly 400 // on saving documents. Because there is no progress set on the MediaDescriptor. 401 // But that's wrong. In case the document was opened hidden, they shouldn't use any progress .-( 402 // They only possible workaround: dont show the parent window here, if the document was opened hidden. 403 sal_Bool bHiddenDoc = sal_False; 404 if (xFrame.is()) 405 { 406 css::uno::Reference< css::frame::XController > xController; 407 css::uno::Reference< css::frame::XModel > xModel ; 408 xController = xFrame->getController(); 409 if (xController.is()) 410 xModel = xController->getModel(); 411 if (xModel.is()) 412 { 413 ::comphelper::MediaDescriptor lDocArgs(xModel->getArgs()); 414 bHiddenDoc = lDocArgs.getUnpackedValueOrDefault( 415 ::comphelper::MediaDescriptor::PROP_HIDDEN(), 416 (sal_Bool)sal_False); 417 } 418 } 419 420 if (bHiddenDoc) 421 return; 422 423 // OK: The document was not opened in hidden mode ... 424 // and the window isn't already visible. 425 // Show it and bring it to front. 426 // But before we have to be sure, that our internal used helper progress 427 // is visible too. 428 impl_showProgress(); 429 430 ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex()); 431 Window* pWindow = VCLUnoHelper::GetWindow(xParentWindow); 432 if ( pWindow ) 433 { 434 bool bForceFrontAndFocus(false); 435 ::comphelper::ConfigurationHelper::readDirectKey( 436 xSMGR, 437 ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/View"), 438 ::rtl::OUString::createFromAscii("NewDocumentHandling"), 439 ::rtl::OUString::createFromAscii("ForceFocusAndToFront"), 440 ::comphelper::ConfigurationHelper::E_READONLY) >>= bForceFrontAndFocus; 441 442 pWindow->Show(sal_True, bForceFrontAndFocus ? SHOW_FOREGROUNDTASK : 0 ); 443 } 444 445 /* 446 #i75167# dont disturb window manager handling .-) 447 css::uno::Reference< css::awt::XTopWindow > xParentWindowTop(xParentWindow, css::uno::UNO_QUERY); 448 if (xParentWindowTop.is()) 449 xParentWindowTop->toFront(); 450 */ 451 } 452 453 //----------------------------------------------- 454 void StatusIndicatorFactory::impl_createProgress() 455 { 456 // SAFE -> ---------------------------------- 457 ReadGuard aReadLock(m_aLock); 458 459 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY); 460 css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY); 461 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 462 463 aReadLock.lock(); 464 // <- SAFE ---------------------------------- 465 466 css::uno::Reference< css::task::XStatusIndicator > xProgress; 467 468 if (xWindow.is()) 469 { 470 // use vcl based progress implementation in plugged mode 471 VCLStatusIndicator* pVCLProgress = new VCLStatusIndicator(xSMGR, xWindow); 472 xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pVCLProgress), css::uno::UNO_QUERY); 473 } 474 else 475 if (xFrame.is()) 476 { 477 // use frame layouted progress implementation 478 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY); 479 if (xPropSet.is()) 480 { 481 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager; 482 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager; 483 if (xLayoutManager.is()) 484 { 485 xLayoutManager->lock(); 486 xLayoutManager->createElement( PROGRESS_RESOURCE ); 487 xLayoutManager->hideElement( PROGRESS_RESOURCE ); 488 489 css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(PROGRESS_RESOURCE); 490 if (xProgressBar.is()) 491 xProgress = css::uno::Reference< css::task::XStatusIndicator >(xProgressBar->getRealInterface(), css::uno::UNO_QUERY); 492 xLayoutManager->unlock(); 493 } 494 } 495 } 496 497 // SAFE -> ---------------------------------- 498 WriteGuard aWriteLock(m_aLock); 499 m_xProgress = xProgress; 500 aWriteLock.lock(); 501 // <- SAFE ---------------------------------- 502 } 503 504 //----------------------------------------------- 505 void StatusIndicatorFactory::impl_showProgress() 506 { 507 // SAFE -> ---------------------------------- 508 ReadGuard aReadLock(m_aLock); 509 510 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY); 511 css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY); 512 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 513 514 aReadLock.lock(); 515 // <- SAFE ---------------------------------- 516 517 css::uno::Reference< css::task::XStatusIndicator > xProgress; 518 519 if (xFrame.is()) 520 { 521 // use frame layouted progress implementation 522 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY); 523 if (xPropSet.is()) 524 { 525 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager; 526 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager; 527 if (xLayoutManager.is()) 528 { 529 // Be sure that we have always a progress. It can be that our frame 530 // was recycled and therefore the progress was destroyed! 531 // CreateElement does nothing if there is already a valid progress. 532 xLayoutManager->createElement( PROGRESS_RESOURCE ); 533 xLayoutManager->showElement( PROGRESS_RESOURCE ); 534 535 css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(PROGRESS_RESOURCE); 536 if (xProgressBar.is()) 537 xProgress = css::uno::Reference< css::task::XStatusIndicator >(xProgressBar->getRealInterface(), css::uno::UNO_QUERY); 538 } 539 } 540 541 // SAFE -> ---------------------------------- 542 WriteGuard aWriteLock(m_aLock); 543 m_xProgress = xProgress; 544 aWriteLock.lock(); 545 // <- SAFE ---------------------------------- 546 } 547 } 548 549 //----------------------------------------------- 550 void StatusIndicatorFactory::impl_hideProgress() 551 { 552 // SAFE -> ---------------------------------- 553 ReadGuard aReadLock(m_aLock); 554 555 css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY); 556 css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY); 557 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 558 559 aReadLock.lock(); 560 // <- SAFE ---------------------------------- 561 562 if (xFrame.is()) 563 { 564 // use frame layouted progress implementation 565 css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY); 566 if (xPropSet.is()) 567 { 568 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager; 569 xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager; 570 if (xLayoutManager.is()) 571 xLayoutManager->hideElement( PROGRESS_RESOURCE ); 572 } 573 } 574 } 575 576 //----------------------------------------------- 577 void StatusIndicatorFactory::impl_reschedule(sal_Bool bForce) 578 { 579 // SAFE -> 580 ReadGuard aReadLock(m_aLock); 581 if (m_bDisableReschedule) 582 return; 583 aReadLock.unlock(); 584 // <- SAFE 585 586 sal_Bool bReschedule = bForce; 587 if (!bReschedule) 588 { 589 // SAFE -> 590 WriteGuard aWriteLock(m_aLock); 591 bReschedule = m_bAllowReschedule; 592 m_bAllowReschedule = sal_False; 593 aWriteLock.unlock(); 594 // <- SAFE 595 } 596 597 if (!bReschedule) 598 return; 599 600 // SAFE -> 601 WriteGuard aGlobalLock(LockHelper::getGlobalLock()); 602 603 if (m_nInReschedule == 0) 604 { 605 ++m_nInReschedule; 606 aGlobalLock.unlock(); 607 // <- SAFE 608 609 Application::Reschedule(true); 610 611 // SAFE -> 612 aGlobalLock.lock(); 613 --m_nInReschedule; 614 } 615 } 616 617 //----------------------------------------------- 618 void StatusIndicatorFactory::impl_startWakeUpThread() 619 { 620 // SAFE -> 621 WriteGuard aWriteLock(m_aLock); 622 623 if (m_bDisableReschedule) 624 return; 625 626 if (!m_pWakeUp) 627 { 628 m_pWakeUp = new WakeUpThread(this); 629 m_pWakeUp->create(); 630 } 631 aWriteLock.unlock(); 632 // <- SAFE 633 } 634 635 //----------------------------------------------- 636 void StatusIndicatorFactory::impl_stopWakeUpThread() 637 { 638 // SAFE -> 639 WriteGuard aWriteLock(m_aLock); 640 if (m_pWakeUp) 641 { 642 // Thread kill itself after terminate()! 643 m_pWakeUp->terminate(); 644 m_pWakeUp = 0; 645 } 646 aWriteLock.unlock(); 647 // <- SAFE 648 } 649 650 } // namespace framework 651