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