xref: /trunk/main/sal/qa/osl/mutex/osl_Mutex.cxx (revision 33608c82206695bbbe0b645fe8a658bc051dbbbe)
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