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