xref: /trunk/main/sal/qa/osl/mutex/osl_Mutex.cxx (revision 86e1cf34)
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 */
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 */
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 {
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 	}
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:
113 	IncreaseThread( struct resource *pData ): pResource( pData ) { }
114 
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 
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:
141 	DecreaseThread( struct resource *pData ): pResource( pData ) { }
142 
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 
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
179 	PutThread( struct chain* pData ): pChain( pData ) { }
180 
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 
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
217 	HoldThread( Mutex* pMutex ): pMyMutex( pMutex ) { }
218 
219 	~HoldThread( )
220 	{
221 		CPPUNIT_ASSERT_MESSAGE( "#HoldThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
222 	}
223 protected:
224 	Mutex* pMyMutex;
225 
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
239 	WaitThread( Mutex* pMutex ): pMyMutex( pMutex ) { }
240 
241 	~WaitThread( )
242 	{
243 		CPPUNIT_ASSERT_MESSAGE( "#WaitThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
244 	}
245 protected:
246 	Mutex* pMyMutex;
247 
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
263 	GlobalMutexThread( ){ }
264 
265 	~GlobalMutexThread( )
266 	{
267 		CPPUNIT_ASSERT_MESSAGE( "#GlobalMutexThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
268 	}
269 protected:
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 
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 
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 		*/
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 		*/
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.
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
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
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 		*/
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 acquire 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?
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 acquire, 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.
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 
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
597 	GuardThread( Mutex* pMutex ): pMyMutex( pMutex ) { }
598 
599 	~GuardThread( )
600 	{
601 		CPPUNIT_ASSERT_MESSAGE( "#GuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
602 	}
603 protected:
604 	Mutex* pMyMutex;
605 
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.
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 
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, acquire 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
683 	ClearGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {}
684 
685 	~ClearGuardThread( )
686 	{
687 		CPPUNIT_ASSERT_MESSAGE( "#ClearGuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
688 	}
689 protected:
690 	Mutex* pMyMutex;
691 
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:
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 acquire operation when initilized.",
723 				bRes == sal_True );
724 		}
725 
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 acquire 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:
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 
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
825 	ResetGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {}
826 
827 	~ResetGuardThread( )
828 	{
829 		CPPUNIT_ASSERT_MESSAGE( "#ResetGuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
830 	}
831 protected:
832 	Mutex* pMyMutex;
833 
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:
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 acquire operation when initilized.",
862 				bRes == sal_True );
863 		}
864 
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 acquire 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:
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 
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 acquire, 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