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