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