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