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_sal.hxx" 26 27 //------------------------------------------------------------------------ 28 // include files 29 //------------------------------------------------------------------------ 30 #include "cppunit/TestAssert.h" 31 #include "cppunit/TestFixture.h" 32 #include "cppunit/extensions/HelperMacros.h" 33 #include "cppunit/plugin/TestPlugIn.h" 34 #include <osl_Mutex_Const.h> 35 36 using namespace osl; 37 using namespace rtl; 38 39 //------------------------------------------------------------------------ 40 // helper functions 41 //------------------------------------------------------------------------ 42 43 /** print a UNI_CODE String. 44 */ 45 inline void printUString( const ::rtl::OUString & str ) 46 { 47 rtl::OString aString; 48 49 printf("#printUString_u# " ); 50 aString = ::rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US ); 51 printf("%s\n", aString.getStr( ) ); 52 } 53 54 /** print Boolean value. 55 */ 56 inline void printBool( sal_Bool bOk ) 57 { 58 printf("#printBool# " ); 59 ( sal_True == bOk ) ? printf("YES!\n" ): printf("NO!\n" ); 60 } 61 62 /** pause nSec seconds helper function. 63 */ 64 namespace ThreadHelper 65 { 66 void thread_sleep( sal_Int32 _nSec ) 67 { 68 /// print statement in thread process must use fflush() to force display. 69 // t_print("# wait %d seconds. ", _nSec ); 70 fflush(stdout); 71 72 #ifdef WNT //Windows 73 Sleep( _nSec * 1000 ); 74 #endif 75 #if ( defined UNX ) || ( defined OS2 ) //Unix 76 sleep( _nSec ); 77 #endif 78 // printf("# done\n" ); 79 } 80 void thread_sleep_tenth_sec(sal_Int32 _nTenthSec) 81 { 82 #ifdef WNT //Windows 83 Sleep(_nTenthSec * 100 ); 84 #endif 85 #if ( defined UNX ) || ( defined OS2 ) //Unix 86 TimeValue nTV; 87 nTV.Seconds = static_cast<sal_uInt32>( _nTenthSec/10 ); 88 nTV.Nanosec = ( (_nTenthSec%10 ) * 100000000 ); 89 osl_waitThread(&nTV); 90 #endif 91 } 92 } 93 94 95 //------------------------------------------------------------------------ 96 // Beginning of the test cases for osl_Mutex class 97 //------------------------------------------------------------------------ 98 99 100 /** mutually exclusive data 101 */ 102 struct resource { 103 sal_Int32 data1; 104 sal_Int32 data2; 105 Mutex lock; 106 }; 107 108 /** IncreaseThread provide data. 109 */ 110 class IncreaseThread : public Thread 111 { 112 public: 113 IncreaseThread( struct resource *pData ): pResource( pData ) { } 114 115 ~IncreaseThread( ) 116 { 117 CPPUNIT_ASSERT_MESSAGE( "#IncreaseThread does not shutdown properly.\n", sal_False == this -> isRunning( ) ); 118 } 119 protected: 120 struct resource *pResource; 121 122 void SAL_CALL run( ) 123 { 124 pResource->lock.acquire( ); 125 for( sal_Int8 i = 0; i < 3; i++ ) 126 { 127 pResource->data1++; 128 yield( ); //yield() give CPU time to other thread, other thread if not block, they will change the data; 129 } 130 if ( pResource->data2 == 0 ) 131 pResource->data2 = ( pResource->data1 > 0 ? pResource->data1 : 0 - pResource->data1 ); 132 pResource->lock.release(); 133 } 134 }; 135 136 /** DecreaseThread consume data. 137 */ 138 class DecreaseThread : public Thread 139 { 140 public: 141 DecreaseThread( struct resource *pData ): pResource( pData ) { } 142 143 ~DecreaseThread( ) 144 { 145 CPPUNIT_ASSERT_MESSAGE( "#DecreaseThread does not shutdown properly.\n", sal_False == this -> isRunning( ) ); 146 } 147 protected: 148 struct resource *pResource; 149 150 void SAL_CALL run( ) 151 { 152 pResource->lock.acquire( ); 153 for( sal_Int8 i = 0; i < 3; i++ ) 154 { 155 pResource->data1--; 156 yield( ); //yield() give CPU time to other thread, other thread if not block, they will change the data; 157 } 158 if ( pResource->data2 == 0 ) 159 pResource->data2 = ( pResource->data1 > 0 ? pResource->data1 : 0 - pResource->data1 ); 160 pResource->lock.release(); 161 } 162 }; 163 164 165 /** chain structure used in Threads as critical resource 166 */ 167 struct chain { 168 sal_Int32 buffer[ BUFFER_SIZE ]; 169 Mutex lock; 170 sal_Int8 pos; 171 }; 172 173 /** PutThread write to the chain structure in a mutex manner. 174 */ 175 class PutThread : public Thread 176 { 177 public: 178 //get the struct pointer to write data to buffer 179 PutThread( struct chain* pData ): pChain( pData ) { } 180 181 ~PutThread( ) 182 { 183 CPPUNIT_ASSERT_MESSAGE( "#PutThread does not shutdown properly.\n", sal_False == this -> isRunning( ) ); 184 } 185 protected: 186 struct chain* pChain; 187 188 void SAL_CALL run( ) 189 { 190 //block here if the mutex has been acquired 191 pChain->lock.acquire( ); 192 193 //current position in buffer to write 194 sal_Int8 nPos = pChain->pos; 195 oslThreadIdentifier oId = getIdentifier( ); 196 //write data 197 sal_Int8 i; 198 for ( i = 0; i < 5; i++ ) 199 { 200 pChain->buffer[ nPos + i ] = oId; 201 yield( ); 202 } 203 //revise the position 204 pChain->pos = nPos + i; 205 206 //finish writing, release the mutex 207 pChain->lock.release(); 208 } 209 }; 210 211 /** thread for testing Mutex acquire. 212 */ 213 class HoldThread : public Thread 214 { 215 public: 216 //get the Mutex pointer to operate 217 HoldThread( Mutex* pMutex ): pMyMutex( pMutex ) { } 218 219 ~HoldThread( ) 220 { 221 CPPUNIT_ASSERT_MESSAGE( "#HoldThread does not shutdown properly.\n", sal_False == this -> isRunning( ) ); 222 } 223 protected: 224 Mutex* pMyMutex; 225 226 void SAL_CALL run() 227 { 228 // block here if the mutex has been acquired 229 pMyMutex->acquire( ); 230 printf("# Mutex acquired. \n" ); 231 pMyMutex->release( ); 232 } 233 }; 234 235 class WaitThread : public Thread 236 { 237 public: 238 //get the Mutex pointer to operate 239 WaitThread( Mutex* pMutex ): pMyMutex( pMutex ) { } 240 241 ~WaitThread( ) 242 { 243 CPPUNIT_ASSERT_MESSAGE( "#WaitThread does not shutdown properly.\n", sal_False == this -> isRunning( ) ); 244 } 245 protected: 246 Mutex* pMyMutex; 247 248 void SAL_CALL run( ) 249 { 250 // block here if the mutex has been acquired 251 pMyMutex->acquire( ); 252 ThreadHelper::thread_sleep_tenth_sec( 2 ); 253 pMyMutex->release( ); 254 } 255 }; 256 257 /** thread for testing getGlobalMutex. 258 */ 259 class GlobalMutexThread : public Thread 260 { 261 public: 262 //get the Mutex pointer to operate 263 GlobalMutexThread( ){ } 264 265 ~GlobalMutexThread( ) 266 { 267 CPPUNIT_ASSERT_MESSAGE( "#GlobalMutexThread does not shutdown properly.\n", sal_False == this -> isRunning( ) ); 268 } 269 protected: 270 void SAL_CALL run( ) 271 { 272 // block here if the mutex has been acquired 273 Mutex* pGlobalMutex; 274 pGlobalMutex = pGlobalMutex->getGlobalMutex( ); 275 pGlobalMutex->acquire( ); 276 printf("# Global Mutex acquired. \n" ); 277 pGlobalMutex->release( ); 278 } 279 }; 280 281 282 //-------------------------------------------------------------- 283 namespace osl_Mutex 284 { 285 286 /** Test of the osl::Mutex::constructor 287 */ 288 class ctor : public CppUnit::TestFixture 289 { 290 public: 291 // initialise your test code values here. 292 struct chain m_Data; 293 struct resource m_Res; 294 295 void setUp( ) 296 { 297 for ( sal_Int8 i=0; i < BUFFER_SIZE; i++ ) 298 m_Data.buffer[i] = 0; 299 m_Data.pos = 0; 300 301 m_Res.data1 = 0; 302 m_Res.data2 = 0; 303 } 304 305 void tearDown() 306 { 307 } 308 309 /** Create two threads to write data to the same buffer, use Mutex to assure 310 during one thread write data five times, the other thread should not begin writing. 311 the two threads wrote two different datas: their thread ID, so we can check the datas 312 in buffer to know the order of the two threads writing 313 */ 314 void ctor_001() 315 { 316 PutThread myThread1( &m_Data ); 317 PutThread myThread2( &m_Data ); 318 319 myThread1.create( ); 320 myThread2.create( ); 321 322 //wait until the two threads terminate 323 myThread1.join( ); 324 myThread2.join( ); 325 326 sal_Bool bRes = sal_False; 327 328 // every 5 datas should the same 329 // LLA: this is not a good check, it's too fix 330 if (m_Data.buffer[0] == m_Data.buffer[1] && 331 m_Data.buffer[1] == m_Data.buffer[2] && 332 m_Data.buffer[2] == m_Data.buffer[3] && 333 m_Data.buffer[3] == m_Data.buffer[4] && 334 m_Data.buffer[5] == m_Data.buffer[6] && 335 m_Data.buffer[6] == m_Data.buffer[7] && 336 m_Data.buffer[7] == m_Data.buffer[8] && 337 m_Data.buffer[8] == m_Data.buffer[9]) 338 bRes = sal_True; 339 340 /*for (sal_Int8 i=0; i<BUFFER_SIZE; i++) 341 printf("#data in buffer is %d\n", m_Data.buffer[i]); 342 */ 343 344 CPPUNIT_ASSERT_MESSAGE("Mutex ctor", bRes == sal_True); 345 346 } 347 348 /** Create two threads to write data to operate on the same number , use Mutex to assure, 349 one thread increase data 3 times, the other thread decrease 3 times, store the operate 350 result when the first thread complete, if it is interrupt by the other thread, the stored 351 number will not be 3. 352 */ 353 void ctor_002() 354 { 355 IncreaseThread myThread1( &m_Res ); 356 DecreaseThread myThread2( &m_Res ); 357 358 myThread1.create( ); 359 myThread2.create( ); 360 361 //wait until the two threads terminate 362 myThread1.join( ); 363 myThread2.join( ); 364 365 sal_Bool bRes = sal_False; 366 367 // every 5 datas should the same 368 if ( ( m_Res.data1 == 0 ) && ( m_Res.data2 == 3 ) ) 369 bRes = sal_True; 370 371 CPPUNIT_ASSERT_MESSAGE( "test Mutex ctor function: increase and decrease a number 3 times without interrupt.", bRes == sal_True ); 372 } 373 374 CPPUNIT_TEST_SUITE( ctor ); 375 CPPUNIT_TEST( ctor_001 ); 376 CPPUNIT_TEST( ctor_002 ); 377 CPPUNIT_TEST_SUITE_END( ); 378 }; // class ctor 379 380 381 /** Test of the osl::Mutex::acquire method 382 */ 383 class acquire : public CppUnit::TestFixture 384 { 385 public: 386 // acquire mutex in main thread, and then call acquire again in myThread, 387 // the child thread should block, wait 2 secs, it still block. 388 // Then release mutex in main thread, the child thread could return from acquire, 389 // and go to exec next statement, so could terminate quickly. 390 void acquire_001( ) 391 { 392 Mutex aMutex; 393 //acquire here 394 sal_Bool bRes = aMutex.acquire( ); 395 // pass the pointer of mutex to child thread 396 HoldThread myThread( &aMutex ); 397 myThread.create( ); 398 399 ThreadHelper::thread_sleep_tenth_sec( 2 ); 400 // if acquire in myThread does not work, 2 secs is long enough, 401 // myThread should terminate now, and bRes1 should be sal_False 402 sal_Bool bRes1 = myThread.isRunning( ); 403 404 aMutex.release( ); 405 ThreadHelper::thread_sleep_tenth_sec( 1 ); 406 // after release mutex, myThread stops blocking and will terminate immediately 407 sal_Bool bRes2 = myThread.isRunning( ); 408 myThread.join( ); 409 410 CPPUNIT_ASSERT_MESSAGE( "Mutex acquire", 411 bRes == sal_True && bRes1 == sal_True && bRes2 == sal_False ); 412 } 413 414 //in the same thread, acquire twice should success 415 void acquire_002() 416 { 417 Mutex aMutex; 418 //acquire here 419 sal_Bool bRes = aMutex.acquire(); 420 sal_Bool bRes1 = aMutex.acquire(); 421 422 sal_Bool bRes2 = aMutex.tryToAcquire(); 423 424 aMutex.release(); 425 426 CPPUNIT_ASSERT_MESSAGE("Mutex acquire", 427 bRes == sal_True && bRes1 == sal_True && bRes2 == sal_True); 428 429 } 430 431 CPPUNIT_TEST_SUITE( acquire ); 432 CPPUNIT_TEST( acquire_001 ); 433 CPPUNIT_TEST( acquire_002 ); 434 CPPUNIT_TEST_SUITE_END( ); 435 }; // class acquire 436 437 438 /** Test of the osl::Mutex::tryToAcquire method 439 */ 440 class tryToAcquire : public CppUnit::TestFixture 441 { 442 public: 443 // First let child thread acquire the mutex, and wait 2 secs, during the 2 secs, 444 // in main thread, tryToAcquire mutex should return False 445 // then after the child thread terminated, tryToAcquire should return True 446 void tryToAcquire_001() 447 { 448 Mutex aMutex; 449 WaitThread myThread(&aMutex); 450 myThread.create(); 451 452 // ensure the child thread acquire the mutex 453 ThreadHelper::thread_sleep_tenth_sec(1); 454 455 sal_Bool bRes1 = aMutex.tryToAcquire(); 456 457 if (bRes1 == sal_True) 458 aMutex.release(); 459 // wait the child thread terminate 460 myThread.join(); 461 462 sal_Bool bRes2 = aMutex.tryToAcquire(); 463 464 if (bRes2 == sal_True) 465 aMutex.release(); 466 467 CPPUNIT_ASSERT_MESSAGE("Try to acquire Mutex", 468 bRes1 == sal_False && bRes2 == sal_True); 469 } 470 471 CPPUNIT_TEST_SUITE(tryToAcquire); 472 CPPUNIT_TEST(tryToAcquire_001); 473 CPPUNIT_TEST_SUITE_END(); 474 }; // class tryToAcquire 475 476 /** Test of the osl::Mutex::release method 477 */ 478 class release : public CppUnit::TestFixture 479 { 480 public: 481 /** acquire/release are not used in pairs: after child thread acquired mutex, 482 the main thread release it, then any thread could acquire it. 483 */ 484 void release_001() 485 { 486 Mutex aMutex; 487 WaitThread myThread( &aMutex ); 488 myThread.create( ); 489 490 // ensure the child thread acquire the mutex 491 ThreadHelper::thread_sleep_tenth_sec( 1 ); 492 493 sal_Bool bRunning = myThread.isRunning( ); 494 sal_Bool bRes1 = aMutex.tryToAcquire( ); 495 // wait the child thread terminate 496 myThread.join( ); 497 498 sal_Bool bRes2 = aMutex.tryToAcquire( ); 499 500 if ( bRes2 == sal_True ) 501 aMutex.release( ); 502 503 CPPUNIT_ASSERT_MESSAGE( "release Mutex: try to acquire before and after the mutex has been released", 504 bRes1 == sal_False && bRes2 == sal_True && bRunning == sal_True ); 505 506 } 507 508 // how about release twice? 509 void release_002() 510 { 511 // LLA: is this a real test? 512 #if 0 513 Mutex aMutex; 514 sal_Bool bRes1 = aMutex.release( ); 515 sal_Bool bRes2 = aMutex.release( ); 516 517 CPPUNIT_ASSERT_MESSAGE( "release Mutex: mutex should not be released without acquire, should not release twice. although the behaviour is still under discussion, this test is passed on (LINUX), not passed on (SOLARIS)&(WINDOWS)", 518 bRes1 == sal_False && bRes2 == sal_False ); 519 #endif 520 } 521 522 CPPUNIT_TEST_SUITE( release ); 523 CPPUNIT_TEST( release_001 ); 524 CPPUNIT_TEST( release_002 ); 525 CPPUNIT_TEST_SUITE_END( ); 526 }; // class release 527 528 529 530 /** Test of the osl::Mutex::getGlobalMutex method 531 */ 532 class getGlobalMutex : public CppUnit::TestFixture 533 { 534 public: 535 // initialise your test code values here. 536 void getGlobalMutex_001() 537 { 538 Mutex* pGlobalMutex; 539 pGlobalMutex = pGlobalMutex->getGlobalMutex(); 540 pGlobalMutex->acquire(); 541 542 GlobalMutexThread myThread; 543 myThread.create(); 544 545 ThreadHelper::thread_sleep_tenth_sec(1); 546 sal_Bool bRes1 = myThread.isRunning(); 547 548 pGlobalMutex->release(); 549 ThreadHelper::thread_sleep_tenth_sec(1); 550 // after release mutex, myThread stops blocking and will terminate immediately 551 sal_Bool bRes2 = myThread.isRunning(); 552 553 CPPUNIT_ASSERT_MESSAGE("Global Mutex works", 554 bRes1 == sal_True && bRes2 == sal_False); 555 } 556 557 void getGlobalMutex_002( ) 558 { 559 sal_Bool bRes; 560 561 Mutex *pGlobalMutex; 562 pGlobalMutex = pGlobalMutex->getGlobalMutex( ); 563 pGlobalMutex->acquire( ); 564 { 565 Mutex *pGlobalMutex1; 566 pGlobalMutex1 = pGlobalMutex1->getGlobalMutex( ); 567 bRes = pGlobalMutex1->release( ); 568 } 569 570 CPPUNIT_ASSERT_MESSAGE( "Global Mutex works: if the code between {} get the different mutex as the former one, it will return false when release.", 571 bRes == sal_True ); 572 } 573 574 CPPUNIT_TEST_SUITE(getGlobalMutex); 575 CPPUNIT_TEST(getGlobalMutex_001); 576 CPPUNIT_TEST(getGlobalMutex_002); 577 CPPUNIT_TEST_SUITE_END(); 578 }; // class getGlobalMutex 579 580 // ----------------------------------------------------------------------------- 581 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::ctor, "osl_Mutex"); 582 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::acquire, "osl_Mutex"); 583 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::tryToAcquire, "osl_Mutex"); 584 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::release, "osl_Mutex"); 585 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::getGlobalMutex, "osl_Mutex"); 586 } // namespace osl_Mutex 587 588 589 //------------------------------------------------------------------------ 590 // Beginning of the test cases for osl_Guard class 591 //------------------------------------------------------------------------ 592 593 class GuardThread : public Thread 594 { 595 public: 596 //get the Mutex pointer to operate 597 GuardThread( Mutex* pMutex ): pMyMutex( pMutex ) { } 598 599 ~GuardThread( ) 600 { 601 CPPUNIT_ASSERT_MESSAGE( "#GuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) ); 602 } 603 protected: 604 Mutex* pMyMutex; 605 606 void SAL_CALL run( ) 607 { 608 // block here if the mutex has been acquired 609 MutexGuard aGuard( pMyMutex ); 610 ThreadHelper::thread_sleep_tenth_sec( 2 ); 611 } 612 }; 613 614 615 namespace osl_Guard 616 { 617 class ctor : public CppUnit::TestFixture 618 { 619 public: 620 // insert your test code here. 621 void ctor_001() 622 { 623 Mutex aMutex; 624 GuardThread myThread(&aMutex); 625 myThread.create(); 626 627 ThreadHelper::thread_sleep_tenth_sec(1); 628 sal_Bool bRes = aMutex.tryToAcquire(); 629 // after 1 second, the mutex has been guarded, and the child thread should be running 630 sal_Bool bRes1 = myThread.isRunning(); 631 632 myThread.join(); 633 sal_Bool bRes2 = aMutex.tryToAcquire(); 634 635 CPPUNIT_ASSERT_MESSAGE("GuardThread constructor", 636 bRes == sal_False && bRes1 == sal_True && bRes2 == sal_True); 637 } 638 639 void ctor_002( ) 640 { 641 Mutex aMutex; 642 643 /// use reference constructor here 644 MutexGuard myGuard( aMutex ); 645 646 /// the GuardThread will block here when it is initialised. 647 GuardThread myThread( &aMutex ); 648 myThread.create( ); 649 650 /// is it still blocking? 651 ThreadHelper::thread_sleep_tenth_sec( 2 ); 652 sal_Bool bRes = myThread.isRunning( ); 653 654 /// oh, release him. 655 aMutex.release( ); 656 myThread.join( ); 657 658 CPPUNIT_ASSERT_MESSAGE("GuardThread constructor: reference initialization, acquire the mutex before running the thread, then check if it is blocking.", 659 bRes == sal_True); 660 } 661 662 CPPUNIT_TEST_SUITE(ctor); 663 CPPUNIT_TEST(ctor_001); 664 CPPUNIT_TEST(ctor_002); 665 CPPUNIT_TEST_SUITE_END(); 666 }; // class ctor 667 668 // ----------------------------------------------------------------------------- 669 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Guard::ctor, "osl_Guard"); 670 } // namespace osl_Guard 671 672 673 //------------------------------------------------------------------------ 674 // Beginning of the test cases for osl_ClearableGuard class 675 //------------------------------------------------------------------------ 676 677 /** Thread for test ClearableGuard 678 */ 679 class ClearGuardThread : public Thread 680 { 681 public: 682 //get the Mutex pointer to operate 683 ClearGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {} 684 685 ~ClearGuardThread( ) 686 { 687 CPPUNIT_ASSERT_MESSAGE( "#ClearGuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) ); 688 } 689 protected: 690 Mutex* pMyMutex; 691 692 void SAL_CALL run( ) 693 { 694 // acquire the mutex 695 // printf("# ClearGuardThread" ); 696 ClearableMutexGuard aGuard( pMyMutex ); 697 ThreadHelper::thread_sleep( 5 ); 698 699 // release the mutex 700 aGuard.clear( ); 701 ThreadHelper::thread_sleep( 2 ); 702 } 703 }; 704 705 // ----------------------------------------------------------------------------- 706 namespace osl_ClearableGuard 707 { 708 709 class ctor : public CppUnit::TestFixture 710 { 711 public: 712 void ctor_001() 713 { 714 Mutex aMutex; 715 716 /// now, the aMutex has been guarded. 717 ClearableMutexGuard myMutexGuard( &aMutex ); 718 719 /// it will return sal_False if the aMutex has not been Guarded. 720 sal_Bool bRes = aMutex.release( ); 721 722 CPPUNIT_ASSERT_MESSAGE("ClearableMutexGuard constructor, test the acquire operation when initilized.", 723 bRes == sal_True ); 724 } 725 726 void ctor_002( ) 727 { 728 Mutex aMutex; 729 730 /// now, the aMutex has been guarded, this time, we use reference constructor. 731 ClearableMutexGuard myMutexGuard( aMutex ); 732 733 /// it will return sal_False if the aMutex has not been Guarded. 734 sal_Bool bRes = aMutex.release( ); 735 736 CPPUNIT_ASSERT_MESSAGE("ClearableMutexGuard constructor, test the acquire operation when initilized, we use reference constructor this time.", 737 bRes == sal_True ); 738 } 739 740 CPPUNIT_TEST_SUITE(ctor); 741 CPPUNIT_TEST(ctor_001); 742 CPPUNIT_TEST(ctor_002); 743 CPPUNIT_TEST_SUITE_END(); 744 }; // class ctor 745 746 class clear : public CppUnit::TestFixture 747 { 748 public: 749 void clear_001() 750 { 751 Mutex aMutex; 752 ClearGuardThread myThread(&aMutex); 753 myThread.create(); 754 755 TimeValue aTimeVal_befor; 756 osl_getSystemTime( &aTimeVal_befor ); 757 // wait 1 second to assure the child thread has begun 758 ThreadHelper::thread_sleep(1); 759 760 while (1) 761 { 762 if (aMutex.tryToAcquire() == sal_True) 763 { 764 break; 765 } 766 ThreadHelper::thread_sleep(1); 767 } 768 TimeValue aTimeVal_after; 769 osl_getSystemTime( &aTimeVal_after ); 770 sal_Int32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds; 771 printf("nSec is %"SAL_PRIdINT32"\n", nSec); 772 773 myThread.join(); 774 775 CPPUNIT_ASSERT_MESSAGE("ClearableGuard method: clear", 776 nSec < 7 && nSec > 1); 777 } 778 779 void clear_002( ) 780 { 781 Mutex aMutex; 782 783 /// now, the aMutex has been guarded. 784 ClearableMutexGuard myMutexGuard( &aMutex ); 785 786 /// launch the HoldThread, it will be blocked here. 787 HoldThread myThread( &aMutex ); 788 myThread.create( ); 789 790 /// is it blocking? 791 ThreadHelper::thread_sleep_tenth_sec( 4 ); 792 sal_Bool bRes = myThread.isRunning( ); 793 794 /// use clear to release. 795 myMutexGuard.clear( ); 796 myThread.join( ); 797 sal_Bool bRes1 = myThread.isRunning( ); 798 799 CPPUNIT_ASSERT_MESSAGE( "ClearableGuard method: clear, control the HoldThread's running status!", 800 ( sal_True == bRes ) && ( sal_False == bRes1 ) ); 801 } 802 803 CPPUNIT_TEST_SUITE( clear ); 804 CPPUNIT_TEST( clear_001 ); 805 CPPUNIT_TEST( clear_002 ); 806 CPPUNIT_TEST_SUITE_END( ); 807 }; // class clear 808 809 // ----------------------------------------------------------------------------- 810 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( osl_ClearableGuard::ctor, "osl_ClearableGuard" ); 811 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( osl_ClearableGuard::clear, "osl_ClearableGuard" ); 812 } // namespace osl_ClearableGuard 813 814 815 //------------------------------------------------------------------------ 816 // Beginning of the test cases for osl_ResettableGuard class 817 //------------------------------------------------------------------------ 818 819 /** Thread for test ResettableGuard 820 */ 821 class ResetGuardThread : public Thread 822 { 823 public: 824 //get the Mutex pointer to operate 825 ResetGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {} 826 827 ~ResetGuardThread( ) 828 { 829 CPPUNIT_ASSERT_MESSAGE( "#ResetGuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) ); 830 } 831 protected: 832 Mutex* pMyMutex; 833 834 void SAL_CALL run( ) 835 { 836 // acquire the mutex 837 printf("# ResettableGuard\n" ); 838 ResettableMutexGuard aGuard( pMyMutex ); 839 // release the mutex 840 aGuard.clear( ); 841 ThreadHelper::thread_sleep_tenth_sec( 2 ); 842 } 843 }; 844 845 // ----------------------------------------------------------------------------- 846 namespace osl_ResettableGuard 847 { 848 class ctor : public CppUnit::TestFixture 849 { 850 public: 851 void ctor_001() 852 { 853 Mutex aMutex; 854 855 /// now, the aMutex has been guarded. 856 ResettableMutexGuard myMutexGuard( &aMutex ); 857 858 /// it will return sal_False if the aMutex has not been Guarded. 859 sal_Bool bRes = aMutex.release( ); 860 861 CPPUNIT_ASSERT_MESSAGE("ResettableMutexGuard constructor, test the acquire operation when initilized.", 862 bRes == sal_True ); 863 } 864 865 void ctor_002( ) 866 { 867 Mutex aMutex; 868 869 /// now, the aMutex has been guarded, this time, we use reference constructor. 870 ResettableMutexGuard myMutexGuard( aMutex ); 871 872 /// it will return sal_False if the aMutex has not been Guarded. 873 sal_Bool bRes = aMutex.release( ); 874 875 CPPUNIT_ASSERT_MESSAGE( "ResettableMutexGuard constructor, test the acquire operation when initilized, we use reference constructor this time.", 876 bRes == sal_True ); 877 } 878 879 880 CPPUNIT_TEST_SUITE(ctor); 881 CPPUNIT_TEST(ctor_001); 882 CPPUNIT_TEST(ctor_002); 883 CPPUNIT_TEST_SUITE_END(); 884 }; // class ctor 885 886 class reset : public CppUnit::TestFixture 887 { 888 public: 889 void reset_001( ) 890 { 891 Mutex aMutex; 892 ResetGuardThread myThread( &aMutex ); 893 ResettableMutexGuard myMutexGuard( aMutex ); 894 myThread.create( ); 895 896 /// is it running? and clear done? 897 sal_Bool bRes = myThread.isRunning( ); 898 myMutexGuard.clear( ); 899 ThreadHelper::thread_sleep_tenth_sec( 1 ); 900 901 /// if reset is not success, the release will return sal_False 902 myMutexGuard.reset( ); 903 sal_Bool bRes1 = aMutex.release( ); 904 myThread.join( ); 905 906 CPPUNIT_ASSERT_MESSAGE( "ResettableMutexGuard method: reset", 907 ( sal_True == bRes ) && ( sal_True == bRes1 ) ); 908 } 909 910 void reset_002( ) 911 { 912 Mutex aMutex; 913 ResettableMutexGuard myMutexGuard( &aMutex ); 914 915 /// shouldn't release after clear; 916 myMutexGuard.clear( ); 917 sal_Bool bRes = aMutex.release( ); 918 919 /// can release after reset. 920 myMutexGuard.reset( ); 921 sal_Bool bRes1 = aMutex.release( ); 922 923 CPPUNIT_ASSERT_MESSAGE( "ResettableMutexGuard method: reset, release after clear and reset, on Solaris, the mutex can be release without acquire, so it can not passed on (SOLARIS), but not the reason for reset_002", 924 ( sal_False == bRes ) && ( sal_True == bRes1 ) ); 925 } 926 927 CPPUNIT_TEST_SUITE(reset); 928 CPPUNIT_TEST(reset_001); 929 #ifdef LINUX 930 CPPUNIT_TEST(reset_002); 931 #endif 932 CPPUNIT_TEST_SUITE_END(); 933 }; // class reset 934 935 // ----------------------------------------------------------------------------- 936 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ResettableGuard::ctor); 937 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ResettableGuard::reset); 938 } // namespace osl_ResettableGuard 939 940 CPPUNIT_PLUGIN_IMPLEMENT(); 941 942 // The following sets variables for GNU EMACS 943 // Local Variables: 944 // tab-width:4 945 // End: 946