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 */
printUString(const::rtl::OUString & str)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 */
printBool(sal_Bool bOk)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 {
thread_sleep(sal_Int32 _nSec)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 }
thread_sleep_tenth_sec(sal_Int32 _nTenthSec)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:
IncreaseThread(struct resource * pData)115 IncreaseThread( struct resource *pData ): pResource( pData ) { }
116
~IncreaseThread()117 ~IncreaseThread( )
118 {
119 EXPECT_TRUE(sal_False == this -> isRunning( )) << "#IncreaseThread does not shutdown properly.\n";
120 }
121 protected:
122 struct resource *pResource;
123
run()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:
DecreaseThread(struct resource * pData)143 DecreaseThread( struct resource *pData ): pResource( pData ) { }
144
~DecreaseThread()145 ~DecreaseThread( )
146 {
147 EXPECT_TRUE(sal_False == this -> isRunning( )) << "#DecreaseThread does not shutdown properly.\n";
148 }
149 protected:
150 struct resource *pResource;
151
run()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
PutThread(struct chain * pData)181 PutThread( struct chain* pData ): pChain( pData ) { }
182
~PutThread()183 ~PutThread( )
184 {
185 EXPECT_TRUE(sal_False == this -> isRunning( )) << "#PutThread does not shutdown properly.\n";
186 }
187 protected:
188 struct chain* pChain;
189
run()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
HoldThread(Mutex * pMutex)219 HoldThread( Mutex* pMutex ): pMyMutex( pMutex ) { }
220
~HoldThread()221 ~HoldThread( )
222 {
223 EXPECT_TRUE(sal_False == this -> isRunning( )) << "#HoldThread does not shutdown properly.\n";
224 }
225 protected:
226 Mutex* pMyMutex;
227
run()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
WaitThread(Mutex * pMutex)241 WaitThread( Mutex* pMutex ): pMyMutex( pMutex ) { }
242
~WaitThread()243 ~WaitThread( )
244 {
245 EXPECT_TRUE(sal_False == this -> isRunning( )) << "#WaitThread does not shutdown properly.\n";
246 }
247 protected:
248 Mutex* pMyMutex;
249
run()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
GlobalMutexThread()265 GlobalMutexThread( ){ }
266
~GlobalMutexThread()267 ~GlobalMutexThread( )
268 {
269 EXPECT_TRUE(sal_False == this -> isRunning( )) << "#GlobalMutexThread does not shutdown properly.\n";
270 }
271 protected:
run()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
SetUp()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
TearDown()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 */
TEST_F(MutexConstructor,ctor_001)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 */
TEST_F(MutexConstructor,ctor_002)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.
TEST_F(acquire,acquire_001)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
TEST_F(acquire,acquire_002)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
TEST_F(tryToAcquire,tryToAcquire_001)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 */
TEST_F(release,release_001)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?
TEST_F(release,release_002)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.
TEST_F(getGlobalMutex,getGlobalMutex_001)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
TEST_F(getGlobalMutex,getGlobalMutex_002)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
GuardThread(Mutex * pMutex)566 GuardThread( Mutex* pMutex ): pMyMutex( pMutex ) { }
567
~GuardThread()568 ~GuardThread( )
569 {
570 EXPECT_TRUE(sal_False == this -> isRunning( )) << "#GuardThread does not shutdown properly.\n";
571 }
572 protected:
573 Mutex* pMyMutex;
574
run()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.
TEST_F(GuardThreadConstructor,ctor_001)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
TEST_F(GuardThreadConstructor,ctor_002)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
ClearGuardThread(Mutex * pMutex)644 ClearGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {}
645
~ClearGuardThread()646 ~ClearGuardThread( )
647 {
648 EXPECT_TRUE(sal_False == this -> isRunning( )) << "#ClearGuardThread does not shutdown properly.\n";
649 }
650 protected:
651 Mutex* pMyMutex;
652
run()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
TEST_F(ClearableGuardConstructor,ctor_001)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
TEST_F(ClearableGuardConstructor,ctor_002)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
TEST_F(clear,clear_001)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
TEST_F(clear,clear_002)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
ResetGuardThread(Mutex * pMutex)771 ResetGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {}
772
~ResetGuardThread()773 ~ResetGuardThread( )
774 {
775 EXPECT_TRUE(sal_False == this -> isRunning( )) << "#ResetGuardThread does not shutdown properly.\n";
776 }
777 protected:
778 Mutex* pMyMutex;
779
run()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
TEST_F(ctor,ctor_001)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
TEST_F(ctor,ctor_002)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
TEST_F(reset,reset_001)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
TEST_F(reset,reset_002)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
main(int argc,char ** argv)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