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