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