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