xref: /trunk/main/sal/qa/osl/mutex/osl_Mutex.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sal.hxx"
30 
31 //------------------------------------------------------------------------
32 // include files
33 //------------------------------------------------------------------------
34 #include "cppunit/TestAssert.h"
35 #include "cppunit/TestFixture.h"
36 #include "cppunit/extensions/HelperMacros.h"
37 #include "cppunit/plugin/TestPlugIn.h"
38 #include <osl_Mutex_Const.h>
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         CPPUNIT_ASSERT_MESSAGE( "#IncreaseThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
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         CPPUNIT_ASSERT_MESSAGE( "#DecreaseThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
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         CPPUNIT_ASSERT_MESSAGE( "#PutThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
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         CPPUNIT_ASSERT_MESSAGE( "#HoldThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
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         CPPUNIT_ASSERT_MESSAGE( "#WaitThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
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         CPPUNIT_ASSERT_MESSAGE( "#GlobalMutexThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
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 ctor : public CppUnit::TestFixture
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 
313         /** Create two threads to write data to the same buffer, use Mutex to assure
314             during one thread write data five times, the other thread should not begin writing.
315             the two threads wrote two different datas: their thread ID, so we can check the datas
316             in buffer to know the order of the two threads writing
317         */
318         void ctor_001()
319         {
320             PutThread myThread1( &m_Data );
321             PutThread myThread2( &m_Data );
322 
323             myThread1.create( );
324             myThread2.create( );
325 
326             //wait until the two threads terminate
327             myThread1.join( );
328             myThread2.join( );
329 
330             sal_Bool bRes = sal_False;
331 
332             // every 5 datas should the same
333             // LLA: this is not a good check, it's too fix
334             if (m_Data.buffer[0] == m_Data.buffer[1] &&
335                 m_Data.buffer[1] == m_Data.buffer[2] &&
336                 m_Data.buffer[2] == m_Data.buffer[3] &&
337                 m_Data.buffer[3] == m_Data.buffer[4] &&
338                 m_Data.buffer[5] == m_Data.buffer[6] &&
339                 m_Data.buffer[6] == m_Data.buffer[7] &&
340                 m_Data.buffer[7] == m_Data.buffer[8] &&
341                 m_Data.buffer[8] == m_Data.buffer[9])
342                 bRes = sal_True;
343 
344             /*for (sal_Int8 i=0; i<BUFFER_SIZE; i++)
345                 printf("#data in buffer is %d\n", m_Data.buffer[i]);
346             */
347 
348             CPPUNIT_ASSERT_MESSAGE("Mutex ctor", bRes == sal_True);
349 
350         }
351 
352         /** Create two threads to write data to operate on the same number , use Mutex to assure,
353             one thread increase data 3 times, the other thread decrease 3 times, store the operate
354             result when the first thread complete, if it is interrupt by the other thread, the stored
355             number will not be 3.
356         */
357         void ctor_002()
358         {
359             IncreaseThread myThread1( &m_Res );
360             DecreaseThread myThread2( &m_Res );
361 
362             myThread1.create( );
363             myThread2.create( );
364 
365             //wait until the two threads terminate
366             myThread1.join( );
367             myThread2.join( );
368 
369             sal_Bool bRes = sal_False;
370 
371             // every 5 datas should the same
372             if ( ( m_Res.data1 == 0 ) && ( m_Res.data2 == 3 ) )
373                 bRes = sal_True;
374 
375             CPPUNIT_ASSERT_MESSAGE( "test Mutex ctor function: increase and decrease a number 3 times without interrupt.", bRes == sal_True );
376         }
377 
378         CPPUNIT_TEST_SUITE( ctor );
379         CPPUNIT_TEST( ctor_001 );
380         CPPUNIT_TEST( ctor_002 );
381         CPPUNIT_TEST_SUITE_END( );
382     }; // class ctor
383 
384 
385     /** Test of the osl::Mutex::acquire method
386      */
387     class acquire : public CppUnit::TestFixture
388     {
389     public:
390         // acquire mutex in main thread, and then call acquire again in myThread,
391         // the child thread should block, wait 2 secs, it still block.
392         // Then release mutex in main thread, the child thread could return from acquire,
393         // and go to exec next statement, so could terminate quickly.
394         void acquire_001( )
395         {
396             Mutex aMutex;
397             //acquire here
398             sal_Bool bRes = aMutex.acquire( );
399             // pass the pointer of mutex to child thread
400             HoldThread myThread( &aMutex );
401             myThread.create( );
402 
403             ThreadHelper::thread_sleep_tenth_sec( 2 );
404             // if acquire in myThread does not work, 2 secs is long enough,
405             // myThread should terminate now, and bRes1 should be sal_False
406             sal_Bool bRes1 = myThread.isRunning( );
407 
408             aMutex.release( );
409             ThreadHelper::thread_sleep_tenth_sec( 1 );
410             // after release mutex, myThread stops blocking and will terminate immediately
411             sal_Bool bRes2 = myThread.isRunning( );
412             myThread.join( );
413 
414             CPPUNIT_ASSERT_MESSAGE( "Mutex acquire",
415                 bRes == sal_True && bRes1 == sal_True && bRes2 == sal_False );
416         }
417 
418         //in the same thread, acquire twice should success
419         void acquire_002()
420         {
421             Mutex aMutex;
422             //acquire here
423             sal_Bool bRes = aMutex.acquire();
424             sal_Bool bRes1 = aMutex.acquire();
425 
426             sal_Bool bRes2 = aMutex.tryToAcquire();
427 
428             aMutex.release();
429 
430             CPPUNIT_ASSERT_MESSAGE("Mutex acquire",
431                 bRes == sal_True && bRes1 == sal_True && bRes2 == sal_True);
432 
433         }
434 
435         CPPUNIT_TEST_SUITE( acquire );
436         CPPUNIT_TEST( acquire_001 );
437         CPPUNIT_TEST( acquire_002 );
438         CPPUNIT_TEST_SUITE_END( );
439     }; // class acquire
440 
441 
442     /** Test of the osl::Mutex::tryToAcquire method
443      */
444     class tryToAcquire : public CppUnit::TestFixture
445     {
446     public:
447         // First let child thread acquire the mutex, and wait 2 secs, during the 2 secs,
448         // in main thread, tryToAcquire mutex should return False
449         // then after the child thread terminated, tryToAcquire should return True
450         void tryToAcquire_001()
451         {
452             Mutex aMutex;
453             WaitThread myThread(&aMutex);
454             myThread.create();
455 
456             // ensure the child thread acquire the mutex
457             ThreadHelper::thread_sleep_tenth_sec(1);
458 
459             sal_Bool bRes1 = aMutex.tryToAcquire();
460 
461             if (bRes1 == sal_True)
462                 aMutex.release();
463             // wait the child thread terminate
464             myThread.join();
465 
466             sal_Bool bRes2 = aMutex.tryToAcquire();
467 
468             if (bRes2 == sal_True)
469                 aMutex.release();
470 
471         CPPUNIT_ASSERT_MESSAGE("Try to acquire Mutex",
472                 bRes1 == sal_False && bRes2 == sal_True);
473         }
474 
475         CPPUNIT_TEST_SUITE(tryToAcquire);
476         CPPUNIT_TEST(tryToAcquire_001);
477         CPPUNIT_TEST_SUITE_END();
478     }; // class tryToAcquire
479 
480     /** Test of the osl::Mutex::release method
481      */
482     class release : public CppUnit::TestFixture
483     {
484     public:
485         /** acquire/release are not used in pairs: after child thread acquired mutex,
486             the main thread release it, then any thread could acquire it.
487         */
488         void release_001()
489         {
490             Mutex aMutex;
491             WaitThread myThread( &aMutex );
492             myThread.create( );
493 
494             // ensure the child thread acquire the mutex
495             ThreadHelper::thread_sleep_tenth_sec( 1 );
496 
497             sal_Bool bRunning = myThread.isRunning( );
498             sal_Bool bRes1 = aMutex.tryToAcquire( );
499             // wait the child thread terminate
500             myThread.join( );
501 
502             sal_Bool bRes2 = aMutex.tryToAcquire( );
503 
504             if ( bRes2 == sal_True )
505                 aMutex.release( );
506 
507             CPPUNIT_ASSERT_MESSAGE( "release Mutex: try to aquire before and after the mutex has been released",
508                 bRes1 == sal_False && bRes2 == sal_True && bRunning == sal_True );
509 
510         }
511 
512         // how about release twice?
513         void release_002()
514         {
515 // LLA: is this a real test?
516 #if 0
517             Mutex aMutex;
518             sal_Bool bRes1 = aMutex.release( );
519             sal_Bool bRes2 = aMutex.release( );
520 
521             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)",
522                 bRes1 == sal_False && bRes2 == sal_False );
523 #endif
524         }
525 
526         CPPUNIT_TEST_SUITE( release );
527         CPPUNIT_TEST( release_001 );
528         CPPUNIT_TEST( release_002 );
529         CPPUNIT_TEST_SUITE_END( );
530     }; // class release
531 
532 
533 
534     /** Test of the osl::Mutex::getGlobalMutex method
535      */
536     class getGlobalMutex : public CppUnit::TestFixture
537     {
538     public:
539         // initialise your test code values here.
540         void getGlobalMutex_001()
541         {
542             Mutex* pGlobalMutex;
543             pGlobalMutex = pGlobalMutex->getGlobalMutex();
544             pGlobalMutex->acquire();
545 
546             GlobalMutexThread myThread;
547             myThread.create();
548 
549             ThreadHelper::thread_sleep_tenth_sec(1);
550             sal_Bool bRes1 = myThread.isRunning();
551 
552             pGlobalMutex->release();
553             ThreadHelper::thread_sleep_tenth_sec(1);
554             // after release mutex, myThread stops blocking and will terminate immediately
555             sal_Bool bRes2 = myThread.isRunning();
556 
557             CPPUNIT_ASSERT_MESSAGE("Global Mutex works",
558                 bRes1 == sal_True && bRes2 == sal_False);
559         }
560 
561         void getGlobalMutex_002( )
562         {
563             sal_Bool bRes;
564 
565             Mutex *pGlobalMutex;
566             pGlobalMutex = pGlobalMutex->getGlobalMutex( );
567             pGlobalMutex->acquire( );
568             {
569                 Mutex *pGlobalMutex1;
570                 pGlobalMutex1 = pGlobalMutex1->getGlobalMutex( );
571                 bRes = pGlobalMutex1->release( );
572             }
573 
574             CPPUNIT_ASSERT_MESSAGE( "Global Mutex works: if the code between {} get the different mutex as the former one, it will return false when release.",
575                 bRes == sal_True );
576         }
577 
578         CPPUNIT_TEST_SUITE(getGlobalMutex);
579         CPPUNIT_TEST(getGlobalMutex_001);
580         CPPUNIT_TEST(getGlobalMutex_002);
581         CPPUNIT_TEST_SUITE_END();
582     }; // class getGlobalMutex
583 
584 // -----------------------------------------------------------------------------
585 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::ctor, "osl_Mutex");
586 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::acquire, "osl_Mutex");
587 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::tryToAcquire, "osl_Mutex");
588 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::release, "osl_Mutex");
589 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Mutex::getGlobalMutex, "osl_Mutex");
590 } // namespace osl_Mutex
591 
592 
593 //------------------------------------------------------------------------
594 // Beginning of the test cases for osl_Guard class
595 //------------------------------------------------------------------------
596 
597 class GuardThread : public Thread
598 {
599 public:
600     //get the Mutex pointer to operate
601     GuardThread( Mutex* pMutex ): pMyMutex( pMutex ) { }
602 
603     ~GuardThread( )
604     {
605         CPPUNIT_ASSERT_MESSAGE( "#GuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
606     }
607 protected:
608     Mutex* pMyMutex;
609 
610     void SAL_CALL run( )
611     {
612         // block here if the mutex has been acquired
613         MutexGuard aGuard( pMyMutex );
614         ThreadHelper::thread_sleep_tenth_sec( 2 );
615     }
616 };
617 
618 
619 namespace osl_Guard
620 {
621     class ctor : public CppUnit::TestFixture
622     {
623     public:
624         // insert your test code here.
625         void ctor_001()
626         {
627             Mutex aMutex;
628             GuardThread myThread(&aMutex);
629             myThread.create();
630 
631             ThreadHelper::thread_sleep_tenth_sec(1);
632             sal_Bool bRes = aMutex.tryToAcquire();
633             // after 1 second, the mutex has been guarded, and the child thread should be running
634             sal_Bool bRes1 = myThread.isRunning();
635 
636             myThread.join();
637             sal_Bool bRes2 = aMutex.tryToAcquire();
638 
639             CPPUNIT_ASSERT_MESSAGE("GuardThread constructor",
640                 bRes == sal_False && bRes1 == sal_True && bRes2 == sal_True);
641         }
642 
643         void ctor_002( )
644         {
645             Mutex aMutex;
646 
647             /// use reference constructor here
648             MutexGuard myGuard( aMutex );
649 
650             /// the GuardThread will block here when it is initialised.
651             GuardThread myThread( &aMutex );
652             myThread.create( );
653 
654             /// is it still blocking?
655             ThreadHelper::thread_sleep_tenth_sec( 2 );
656             sal_Bool bRes = myThread.isRunning( );
657 
658             /// oh, release him.
659             aMutex.release( );
660             myThread.join( );
661 
662             CPPUNIT_ASSERT_MESSAGE("GuardThread constructor: reference initialization, aquire the mutex before running the thread, then check if it is blocking.",
663                 bRes == sal_True);
664         }
665 
666         CPPUNIT_TEST_SUITE(ctor);
667         CPPUNIT_TEST(ctor_001);
668         CPPUNIT_TEST(ctor_002);
669         CPPUNIT_TEST_SUITE_END();
670     }; // class ctor
671 
672 // -----------------------------------------------------------------------------
673 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Guard::ctor, "osl_Guard");
674 } // namespace osl_Guard
675 
676 
677 //------------------------------------------------------------------------
678 // Beginning of the test cases for osl_ClearableGuard class
679 //------------------------------------------------------------------------
680 
681 /** Thread for test ClearableGuard
682  */
683 class ClearGuardThread : public Thread
684 {
685 public:
686     //get the Mutex pointer to operate
687     ClearGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {}
688 
689     ~ClearGuardThread( )
690     {
691         CPPUNIT_ASSERT_MESSAGE( "#ClearGuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
692     }
693 protected:
694     Mutex* pMyMutex;
695 
696     void SAL_CALL run( )
697     {
698         // acquire the mutex
699         // printf("# ClearGuardThread" );
700         ClearableMutexGuard aGuard( pMyMutex );
701         ThreadHelper::thread_sleep( 5 );
702 
703         // release the mutex
704         aGuard.clear( );
705         ThreadHelper::thread_sleep( 2 );
706     }
707 };
708 
709 // -----------------------------------------------------------------------------
710 namespace osl_ClearableGuard
711 {
712 
713     class ctor : public CppUnit::TestFixture
714     {
715     public:
716         void ctor_001()
717         {
718             Mutex aMutex;
719 
720             /// now, the aMutex has been guarded.
721             ClearableMutexGuard myMutexGuard( &aMutex );
722 
723             /// it will return sal_False if the aMutex has not been Guarded.
724             sal_Bool bRes = aMutex.release( );
725 
726             CPPUNIT_ASSERT_MESSAGE("ClearableMutexGuard constructor, test the aquire operation when initilized.",
727                 bRes == sal_True );
728         }
729 
730         void ctor_002( )
731         {
732             Mutex aMutex;
733 
734             /// now, the aMutex has been guarded, this time, we use reference constructor.
735             ClearableMutexGuard myMutexGuard( aMutex );
736 
737             /// it will return sal_False if the aMutex has not been Guarded.
738             sal_Bool bRes = aMutex.release( );
739 
740             CPPUNIT_ASSERT_MESSAGE("ClearableMutexGuard constructor, test the aquire operation when initilized, we use reference constructor this time.",
741                 bRes == sal_True );
742         }
743 
744         CPPUNIT_TEST_SUITE(ctor);
745         CPPUNIT_TEST(ctor_001);
746         CPPUNIT_TEST(ctor_002);
747         CPPUNIT_TEST_SUITE_END();
748     }; // class ctor
749 
750     class clear : public CppUnit::TestFixture
751     {
752     public:
753         void clear_001()
754         {
755             Mutex aMutex;
756             ClearGuardThread myThread(&aMutex);
757             myThread.create();
758 
759             TimeValue aTimeVal_befor;
760             osl_getSystemTime( &aTimeVal_befor );
761             // wait 1 second to assure the child thread has begun
762             ThreadHelper::thread_sleep(1);
763 
764             while (1)
765             {
766                 if (aMutex.tryToAcquire() == sal_True)
767                 {
768                     break;
769                 }
770                 ThreadHelper::thread_sleep(1);
771             }
772             TimeValue aTimeVal_after;
773             osl_getSystemTime( &aTimeVal_after );
774             sal_Int32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
775             printf("nSec is %"SAL_PRIdINT32"\n", nSec);
776 
777             myThread.join();
778 
779             CPPUNIT_ASSERT_MESSAGE("ClearableGuard method: clear",
780                 nSec < 7 && nSec > 1);
781         }
782 
783         void clear_002( )
784         {
785             Mutex aMutex;
786 
787             /// now, the aMutex has been guarded.
788             ClearableMutexGuard myMutexGuard( &aMutex );
789 
790             /// launch the HoldThread, it will be blocked here.
791             HoldThread myThread( &aMutex );
792             myThread.create( );
793 
794             /// is it blocking?
795             ThreadHelper::thread_sleep_tenth_sec( 4 );
796             sal_Bool bRes = myThread.isRunning( );
797 
798             /// use clear to release.
799             myMutexGuard.clear( );
800             myThread.join( );
801             sal_Bool bRes1 = myThread.isRunning( );
802 
803             CPPUNIT_ASSERT_MESSAGE( "ClearableGuard method: clear, control the HoldThread's running status!",
804                 ( sal_True == bRes ) && ( sal_False == bRes1 ) );
805         }
806 
807         CPPUNIT_TEST_SUITE( clear );
808         CPPUNIT_TEST( clear_001 );
809         CPPUNIT_TEST( clear_002 );
810         CPPUNIT_TEST_SUITE_END( );
811     }; // class clear
812 
813 // -----------------------------------------------------------------------------
814 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( osl_ClearableGuard::ctor, "osl_ClearableGuard" );
815 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( osl_ClearableGuard::clear, "osl_ClearableGuard" );
816 } // namespace osl_ClearableGuard
817 
818 
819 //------------------------------------------------------------------------
820 // Beginning of the test cases for osl_ResettableGuard class
821 //------------------------------------------------------------------------
822 
823 /** Thread for test ResettableGuard
824  */
825 class ResetGuardThread : public Thread
826 {
827 public:
828     //get the Mutex pointer to operate
829     ResetGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {}
830 
831     ~ResetGuardThread( )
832     {
833         CPPUNIT_ASSERT_MESSAGE( "#ResetGuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
834     }
835 protected:
836     Mutex* pMyMutex;
837 
838     void SAL_CALL run( )
839     {
840         // acquire the mutex
841         printf("# ResettableGuard\n" );
842         ResettableMutexGuard aGuard( pMyMutex );
843         // release the mutex
844         aGuard.clear( );
845         ThreadHelper::thread_sleep_tenth_sec( 2 );
846     }
847 };
848 
849 // -----------------------------------------------------------------------------
850 namespace osl_ResettableGuard
851 {
852     class ctor : public CppUnit::TestFixture
853     {
854     public:
855         void ctor_001()
856         {
857             Mutex aMutex;
858 
859             /// now, the aMutex has been guarded.
860             ResettableMutexGuard myMutexGuard( &aMutex );
861 
862             /// it will return sal_False if the aMutex has not been Guarded.
863             sal_Bool bRes = aMutex.release( );
864 
865             CPPUNIT_ASSERT_MESSAGE("ResettableMutexGuard constructor, test the aquire operation when initilized.",
866                 bRes == sal_True );
867         }
868 
869         void ctor_002( )
870         {
871             Mutex aMutex;
872 
873             /// now, the aMutex has been guarded, this time, we use reference constructor.
874             ResettableMutexGuard myMutexGuard( aMutex );
875 
876             /// it will return sal_False if the aMutex has not been Guarded.
877             sal_Bool bRes = aMutex.release( );
878 
879             CPPUNIT_ASSERT_MESSAGE( "ResettableMutexGuard constructor, test the aquire operation when initilized, we use reference constructor this time.",
880                 bRes == sal_True );
881         }
882 
883 
884         CPPUNIT_TEST_SUITE(ctor);
885         CPPUNIT_TEST(ctor_001);
886         CPPUNIT_TEST(ctor_002);
887         CPPUNIT_TEST_SUITE_END();
888     }; // class ctor
889 
890     class reset : public CppUnit::TestFixture
891     {
892     public:
893         void reset_001( )
894         {
895             Mutex aMutex;
896             ResetGuardThread myThread( &aMutex );
897             ResettableMutexGuard myMutexGuard( aMutex );
898             myThread.create( );
899 
900             /// is it running? and clear done?
901             sal_Bool bRes = myThread.isRunning( );
902             myMutexGuard.clear( );
903             ThreadHelper::thread_sleep_tenth_sec( 1 );
904 
905             /// if reset is not success, the release will return sal_False
906             myMutexGuard.reset( );
907             sal_Bool bRes1 = aMutex.release( );
908             myThread.join( );
909 
910             CPPUNIT_ASSERT_MESSAGE( "ResettableMutexGuard method: reset",
911                 ( sal_True == bRes ) && ( sal_True == bRes1 ) );
912         }
913 
914         void reset_002( )
915         {
916             Mutex aMutex;
917             ResettableMutexGuard myMutexGuard( &aMutex );
918 
919             /// shouldn't release after clear;
920             myMutexGuard.clear( );
921             sal_Bool bRes = aMutex.release( );
922 
923             /// can release after reset.
924             myMutexGuard.reset( );
925             sal_Bool bRes1 = aMutex.release( );
926 
927             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",
928                 ( sal_False == bRes ) && ( sal_True == bRes1 ) );
929         }
930 
931         CPPUNIT_TEST_SUITE(reset);
932         CPPUNIT_TEST(reset_001);
933 #ifdef LINUX
934         CPPUNIT_TEST(reset_002);
935 #endif
936         CPPUNIT_TEST_SUITE_END();
937     }; // class reset
938 
939 // -----------------------------------------------------------------------------
940 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ResettableGuard::ctor);
941 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ResettableGuard::reset);
942 } // namespace osl_ResettableGuard
943 
944 CPPUNIT_PLUGIN_IMPLEMENT();
945 
946 // The following sets variables for GNU EMACS
947 // Local Variables:
948 // tab-width:4
949 // End:
950