xref: /aoo42x/main/sal/qa/osl/mutex/osl_Mutex.cxx (revision a03c9fa9)
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 #include <tools/prewin.h>
35 #define WIN32_LEAN_AND_MEAN
36 #include <windows.h>
37 #include <tools/postwin.h>
38 #endif
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 		EXPECT_TRUE(sal_False == this -> isRunning( )) << "#IncreaseThread does not shutdown properly.\n";
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 		EXPECT_TRUE(sal_False == this -> isRunning( )) << "#DecreaseThread does not shutdown properly.\n";
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 		EXPECT_TRUE(sal_False == this -> isRunning( )) << "#PutThread does not shutdown properly.\n";
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 		EXPECT_TRUE(sal_False == this -> isRunning( )) << "#HoldThread does not shutdown properly.\n";
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 		EXPECT_TRUE(sal_False == this -> isRunning( )) << "#WaitThread does not shutdown properly.\n";
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 		EXPECT_TRUE(sal_False == this -> isRunning( )) << "#GlobalMutexThread does not shutdown properly.\n";
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 MutexConstructor : public ::testing::Test
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 	}; // class ctor
313 
314 	/** Create two threads to write data to the same buffer, use Mutex to assure
315 		during one thread write data five times, the other thread should not begin writing.
316 		the two threads wrote two different datas: their thread ID, so we can check the datas
317 		in buffer to know the order of the two threads writing
318 	*/
319 	TEST_F(MutexConstructor, ctor_001)
320 	{
321 		PutThread myThread1( &m_Data );
322 		PutThread myThread2( &m_Data );
323 
324 		myThread1.create( );
325 		myThread2.create( );
326 
327 		//wait until the two threads terminate
328 		myThread1.join( );
329 		myThread2.join( );
330 
331 		sal_Bool bRes = sal_False;
332 
333 		// every 5 datas should the same
334         // LLA: this is not a good check, it's too fix
335 		if (m_Data.buffer[0] == m_Data.buffer[1] &&
336 			m_Data.buffer[1] == m_Data.buffer[2] &&
337 			m_Data.buffer[2] == m_Data.buffer[3] &&
338 			m_Data.buffer[3] == m_Data.buffer[4] &&
339 			m_Data.buffer[5] == m_Data.buffer[6] &&
340 			m_Data.buffer[6] == m_Data.buffer[7] &&
341 			m_Data.buffer[7] == m_Data.buffer[8] &&
342 			m_Data.buffer[8] == m_Data.buffer[9])
343 			bRes = sal_True;
344 
345 		/*for (sal_Int8 i=0; i<BUFFER_SIZE; i++)
346 			printf("#data in buffer is %d\n", m_Data.buffer[i]);
347 		*/
348 
349 		ASSERT_TRUE(bRes == sal_True) << "Mutex ctor";
350 
351 	}
352 
353 	/** Create two threads to write data to operate on the same number , use Mutex to assure,
354 		one thread increase data 3 times, the other thread decrease 3 times, store the operate
355 		result when the first thread complete, if it is interrupt by the other thread, the stored
356 		number will not be 3.
357 	*/
358 	TEST_F(MutexConstructor, ctor_002)
359 	{
360 		IncreaseThread myThread1( &m_Res );
361 		DecreaseThread myThread2( &m_Res );
362 
363 		myThread1.create( );
364 		myThread2.create( );
365 
366 		//wait until the two threads terminate
367 		myThread1.join( );
368 		myThread2.join( );
369 
370 		sal_Bool bRes = sal_False;
371 
372 		// every 5 datas should the same
373 		if ( ( m_Res.data1 == 0 ) && ( m_Res.data2 == 3 ) )
374 			bRes = sal_True;
375 
376 		ASSERT_TRUE(bRes == sal_True) << "test Mutex ctor function: increase and decrease a number 3 times without interrupt.";
377 	}
378 
379 
380 	/** Test of the	osl::Mutex::acquire method
381 	 */
382 	class acquire : public ::testing::Test
383 	{
384 	public:
385 	}; // class acquire
386 
387 	// acquire mutex in main thread, and then call acquire again in myThread,
388 	// the child thread should block, wait 2 secs, it still block.
389 	// Then release mutex in main thread, the child thread could return from acquire,
390 	// and go to exec next statement, so could terminate quickly.
391 	TEST_F(acquire, acquire_001 )
392 	{
393 		Mutex aMutex;
394 		//acquire here
395 		sal_Bool bRes = aMutex.acquire( );
396 		// pass the pointer of mutex to child thread
397 		HoldThread myThread( &aMutex );
398 		myThread.create( );
399 
400 		ThreadHelper::thread_sleep_tenth_sec( 2 );
401 		// if acquire in myThread does not work, 2 secs is long enough,
402 		// myThread should terminate now, and bRes1 should be sal_False
403 		sal_Bool bRes1 = myThread.isRunning( );
404 
405 		aMutex.release( );
406 		ThreadHelper::thread_sleep_tenth_sec( 1 );
407 		// after release mutex, myThread stops blocking and will terminate immediately
408 		sal_Bool bRes2 = myThread.isRunning( );
409 		myThread.join( );
410 
411 		ASSERT_TRUE(bRes == sal_True && bRes1 == sal_True && bRes2 == sal_False) << "Mutex acquire";
412 	}
413 
414 	//in the same thread, acquire twice should success
415 	TEST_F(acquire, 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 		ASSERT_TRUE(bRes == sal_True && bRes1 == sal_True && bRes2 == sal_True) << "Mutex acquire";
427 
428 	}
429 
430 
431 	/** Test of the	osl::Mutex::tryToAcquire method
432 	 */
433 	class tryToAcquire : public ::testing::Test
434 	{
435 	public:
436 	}; // class tryToAcquire
437 
438 	// First let child thread acquire the mutex, and wait 2 secs, during the 2 secs,
439 	// in main thread, tryToAcquire mutex should return False
440 	// then after the child thread terminated, tryToAcquire should return True
441 	TEST_F(tryToAcquire, tryToAcquire_001)
442 	{
443 		Mutex aMutex;
444 		WaitThread myThread(&aMutex);
445 		myThread.create();
446 
447 		// ensure the child thread acquire the mutex
448 		ThreadHelper::thread_sleep_tenth_sec(1);
449 
450 		sal_Bool bRes1 = aMutex.tryToAcquire();
451 
452 		if (bRes1 == sal_True)
453 			aMutex.release();
454 		// wait the child thread terminate
455 		myThread.join();
456 
457 		sal_Bool bRes2 = aMutex.tryToAcquire();
458 
459 		if (bRes2 == sal_True)
460 			aMutex.release();
461 
462 	ASSERT_TRUE(bRes1 == sal_False && bRes2 == sal_True) << "Try to acquire Mutex";
463 	}
464 
465 
466 	/** Test of the	osl::Mutex::release method
467 	 */
468 	class release : public ::testing::Test
469 	{
470 	public:
471 	}; // class release
472 
473 	/** acquire/release are not used in pairs: after child thread acquired mutex,
474 		the main thread release it, then any thread could acquire it.
475 	*/
476 	TEST_F(release, release_001)
477 	{
478 		Mutex aMutex;
479 		WaitThread myThread( &aMutex );
480 		myThread.create( );
481 
482 		// ensure the child thread acquire the mutex
483 		ThreadHelper::thread_sleep_tenth_sec( 1 );
484 
485 		sal_Bool bRunning = myThread.isRunning( );
486 		sal_Bool bRes1 = aMutex.tryToAcquire( );
487 		// wait the child thread terminate
488 		myThread.join( );
489 
490 		sal_Bool bRes2 = aMutex.tryToAcquire( );
491 
492 		if ( bRes2 == sal_True )
493 			aMutex.release( );
494 
495 		ASSERT_TRUE(bRes1 == sal_False && bRes2 == sal_True && bRunning == sal_True) << "release Mutex: try to aquire before and after the mutex has been released";
496 
497 	}
498 
499 	// how about release twice?
500 	TEST_F(release, release_002)
501 	{
502 // LLA: is this a real test?
503 #if 0
504 		Mutex aMutex;
505 		sal_Bool bRes1 = aMutex.release( );
506 		sal_Bool bRes2 = aMutex.release( );
507 
508 		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)";
509 #endif
510 	}
511 
512 
513 	/** Test of the	osl::Mutex::getGlobalMutex method
514 	 */
515 	class getGlobalMutex : public ::testing::Test
516 	{
517 	public:
518 	}; // class getGlobalMutex
519 
520 	// initialise your test code values here.
521 	TEST_F(getGlobalMutex, getGlobalMutex_001)
522 	{
523 		Mutex* pGlobalMutex;
524 		pGlobalMutex = pGlobalMutex->getGlobalMutex();
525 		pGlobalMutex->acquire();
526 
527 		GlobalMutexThread myThread;
528 		myThread.create();
529 
530 		ThreadHelper::thread_sleep_tenth_sec(1);
531 		sal_Bool bRes1 = myThread.isRunning();
532 
533 		pGlobalMutex->release();
534 		ThreadHelper::thread_sleep_tenth_sec(1);
535 		// after release mutex, myThread stops blocking and will terminate immediately
536 		sal_Bool bRes2 = myThread.isRunning();
537 
538 		ASSERT_TRUE(bRes1 == sal_True && bRes2 == sal_False) << "Global Mutex works";
539 	}
540 
541 	TEST_F(getGlobalMutex, getGlobalMutex_002 )
542 	{
543 		sal_Bool bRes;
544 
545 		Mutex *pGlobalMutex;
546 		pGlobalMutex = pGlobalMutex->getGlobalMutex( );
547 		pGlobalMutex->acquire( );
548 		{
549 			Mutex *pGlobalMutex1;
550 			pGlobalMutex1 = pGlobalMutex1->getGlobalMutex( );
551 			bRes = pGlobalMutex1->release( );
552 		}
553 
554 		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.";
555 	}
556 
557 } // namespace osl_Mutex
558 
559 
560 //------------------------------------------------------------------------
561 // Beginning of the test cases for osl_Guard class
562 //------------------------------------------------------------------------
563 
564 class GuardThread : public Thread
565 {
566 public:
567 	//get the Mutex pointer to operate
568 	GuardThread( Mutex* pMutex ): pMyMutex( pMutex ) { }
569 
570 	~GuardThread( )
571 	{
572 		EXPECT_TRUE(sal_False == this -> isRunning( )) << "#GuardThread does not shutdown properly.\n";
573 	}
574 protected:
575 	Mutex* pMyMutex;
576 
577 	void SAL_CALL run( )
578 	{
579 		// block here if the mutex has been acquired
580 		MutexGuard aGuard( pMyMutex );
581 		ThreadHelper::thread_sleep_tenth_sec( 2 );
582 	}
583 };
584 
585 
586 namespace osl_Guard
587 {
588 	class GuardThreadConstructor : public ::testing::Test
589 	{
590 	public:
591 	}; // class ctor
592 
593 	// insert your test code here.
594 	TEST_F(GuardThreadConstructor, ctor_001)
595 	{
596 		Mutex aMutex;
597 		GuardThread myThread(&aMutex);
598 		myThread.create();
599 
600 		ThreadHelper::thread_sleep_tenth_sec(1);
601 		sal_Bool bRes = aMutex.tryToAcquire();
602 		// after 1 second, the mutex has been guarded, and the child thread should be running
603 		sal_Bool bRes1 = myThread.isRunning();
604 
605 		myThread.join();
606 		sal_Bool bRes2 = aMutex.tryToAcquire();
607 
608 		ASSERT_TRUE(bRes == sal_False && bRes1 == sal_True && bRes2 == sal_True) << "GuardThread constructor";
609 	}
610 
611 	TEST_F(GuardThreadConstructor, ctor_002 )
612 	{
613 		Mutex aMutex;
614 
615 		/// use reference constructor here
616 		MutexGuard myGuard( aMutex );
617 
618 		/// the GuardThread will block here when it is initialised.
619 		GuardThread myThread( &aMutex );
620 		myThread.create( );
621 
622 		/// is it still blocking?
623 		ThreadHelper::thread_sleep_tenth_sec( 2 );
624 		sal_Bool bRes = myThread.isRunning( );
625 
626 		/// oh, release him.
627 		aMutex.release( );
628 		myThread.join( );
629 
630 		ASSERT_TRUE(bRes == sal_True) << "GuardThread constructor: reference initialization, aquire the mutex before running the thread, then check if it is blocking.";
631 	}
632 
633 } // namespace osl_Guard
634 
635 
636 //------------------------------------------------------------------------
637 // Beginning of the test cases for osl_ClearableGuard class
638 //------------------------------------------------------------------------
639 
640 /** Thread for test ClearableGuard
641  */
642 class ClearGuardThread : public Thread
643 {
644 public:
645 	//get the Mutex pointer to operate
646 	ClearGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {}
647 
648 	~ClearGuardThread( )
649 	{
650 		EXPECT_TRUE(sal_False == this -> isRunning( )) << "#ClearGuardThread does not shutdown properly.\n";
651 	}
652 protected:
653 	Mutex* pMyMutex;
654 
655 	void SAL_CALL run( )
656 	{
657 		// acquire the mutex
658         // printf("# ClearGuardThread" );
659 		ClearableMutexGuard aGuard( pMyMutex );
660 		ThreadHelper::thread_sleep( 5 );
661 
662 		// release the mutex
663 		aGuard.clear( );
664 		ThreadHelper::thread_sleep( 2 );
665 	}
666 };
667 
668 // -----------------------------------------------------------------------------
669 namespace osl_ClearableGuard
670 {
671 
672 	class ClearableGuardConstructor : public ::testing::Test
673 	{
674 	public:
675 	}; // class ctor
676 
677 	TEST_F(ClearableGuardConstructor, ctor_001)
678 	{
679 		Mutex aMutex;
680 
681 		/// now, the aMutex has been guarded.
682 		ClearableMutexGuard myMutexGuard( &aMutex );
683 
684 		/// it will return sal_False if the aMutex has not been Guarded.
685 		sal_Bool bRes = aMutex.release( );
686 
687 		ASSERT_TRUE(bRes == sal_True) << "ClearableMutexGuard constructor, test the aquire operation when initilized.";
688 	}
689 
690 	TEST_F(ClearableGuardConstructor, ctor_002 )
691 	{
692 		Mutex aMutex;
693 
694 		/// now, the aMutex has been guarded, this time, we use reference constructor.
695 		ClearableMutexGuard myMutexGuard( aMutex );
696 
697 		/// it will return sal_False if the aMutex has not been Guarded.
698 		sal_Bool bRes = aMutex.release( );
699 
700 		ASSERT_TRUE(bRes == sal_True) << "ClearableMutexGuard constructor, test the aquire operation when initilized, we use reference constructor this time.";
701 	}
702 
703 	class clear : public ::testing::Test
704 	{
705 	public:
706 	}; // class clear
707 
708 	TEST_F(clear, clear_001)
709 	{
710 		Mutex aMutex;
711 		ClearGuardThread myThread(&aMutex);
712 		myThread.create();
713 
714 		TimeValue aTimeVal_befor;
715 		osl_getSystemTime( &aTimeVal_befor );
716 		// wait 1 second to assure the child thread has begun
717 		ThreadHelper::thread_sleep(1);
718 
719 		while (1)
720 		{
721 			if (aMutex.tryToAcquire() == sal_True)
722             {
723                 break;
724             }
725             ThreadHelper::thread_sleep(1);
726 		}
727 		TimeValue aTimeVal_after;
728 		osl_getSystemTime( &aTimeVal_after );
729 		sal_Int32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
730         printf("nSec is %"SAL_PRIdINT32"\n", nSec);
731 
732 		myThread.join();
733 
734 		ASSERT_TRUE(nSec < 7 && nSec > 1) << "ClearableGuard method: clear";
735 	}
736 
737 	TEST_F(clear, clear_002 )
738 	{
739 		Mutex aMutex;
740 
741 		/// now, the aMutex has been guarded.
742 		ClearableMutexGuard myMutexGuard( &aMutex );
743 
744 		/// launch the HoldThread, it will be blocked here.
745 		HoldThread myThread( &aMutex );
746 		myThread.create( );
747 
748 		/// is it blocking?
749 		ThreadHelper::thread_sleep_tenth_sec( 4 );
750 		sal_Bool bRes = myThread.isRunning( );
751 
752 		/// use clear to release.
753 		myMutexGuard.clear( );
754 		myThread.join( );
755 		sal_Bool bRes1 = myThread.isRunning( );
756 
757 		ASSERT_TRUE(( sal_True == bRes ) && ( sal_False == bRes1 )) << "ClearableGuard method: clear, control the HoldThread's running status!";
758 	}
759 
760 } // namespace osl_ClearableGuard
761 
762 
763 //------------------------------------------------------------------------
764 // Beginning of the test cases for osl_ResettableGuard class
765 //------------------------------------------------------------------------
766 
767 /** Thread for test ResettableGuard
768  */
769 class ResetGuardThread : public Thread
770 {
771 public:
772 	//get the Mutex pointer to operate
773 	ResetGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {}
774 
775 	~ResetGuardThread( )
776 	{
777 		EXPECT_TRUE(sal_False == this -> isRunning( )) << "#ResetGuardThread does not shutdown properly.\n";
778 	}
779 protected:
780 	Mutex* pMyMutex;
781 
782 	void SAL_CALL run( )
783 	{
784 		// acquire the mutex
785 		printf("# ResettableGuard\n" );
786 		ResettableMutexGuard aGuard( pMyMutex );
787 		// release the mutex
788 		aGuard.clear( );
789 		ThreadHelper::thread_sleep_tenth_sec( 2 );
790 	}
791 };
792 
793 // -----------------------------------------------------------------------------
794 namespace osl_ResettableGuard
795 {
796 	class ctor : public ::testing::Test
797 	{
798 	public:
799 	}; // class ctor
800 
801 	TEST_F(ctor, ctor_001)
802 	{
803 		Mutex aMutex;
804 
805 		/// now, the aMutex has been guarded.
806 		ResettableMutexGuard myMutexGuard( &aMutex );
807 
808 		/// it will return sal_False if the aMutex has not been Guarded.
809 		sal_Bool bRes = aMutex.release( );
810 
811 		ASSERT_TRUE(bRes == sal_True) << "ResettableMutexGuard constructor, test the aquire operation when initilized.";
812 	}
813 
814 	TEST_F(ctor, ctor_002 )
815 	{
816 		Mutex aMutex;
817 
818 		/// now, the aMutex has been guarded, this time, we use reference constructor.
819 		ResettableMutexGuard myMutexGuard( aMutex );
820 
821 		/// it will return sal_False if the aMutex has not been Guarded.
822 		sal_Bool bRes = aMutex.release( );
823 
824 		ASSERT_TRUE(bRes == sal_True) << "ResettableMutexGuard constructor, test the aquire operation when initilized, we use reference constructor this time.";
825 	}
826 
827 
828 	class reset : public ::testing::Test
829 	{
830 	public:
831 	}; // class reset
832 
833 
834 	TEST_F(reset, reset_001 )
835 	{
836 		Mutex aMutex;
837 		ResetGuardThread myThread( &aMutex );
838 		ResettableMutexGuard myMutexGuard( aMutex );
839 		myThread.create( );
840 
841 		/// is it running? and clear done?
842 		sal_Bool bRes = myThread.isRunning( );
843 		myMutexGuard.clear( );
844 		ThreadHelper::thread_sleep_tenth_sec( 1 );
845 
846 		/// if reset is not success, the release will return sal_False
847 		myMutexGuard.reset( );
848 		sal_Bool bRes1 = aMutex.release( );
849 		myThread.join( );
850 
851 		ASSERT_TRUE(( sal_True == bRes ) && ( sal_True == bRes1 )) << "ResettableMutexGuard method: reset";
852 	}
853 
854 	TEST_F(reset, reset_002 )
855 	{
856 #ifdef LINUX
857 		Mutex aMutex;
858 		ResettableMutexGuard myMutexGuard( &aMutex );
859 
860 		/// shouldn't release after clear;
861 		myMutexGuard.clear( );
862 		sal_Bool bRes = aMutex.release( );
863 
864 		/// can release after reset.
865 		myMutexGuard.reset( );
866 		sal_Bool bRes1 = aMutex.release( );
867 
868 		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";
869 #endif
870 	}
871 
872 } // namespace osl_ResettableGuard
873 
874 int main(int argc, char **argv)
875 {
876     ::testing::InitGoogleTest(&argc, argv);
877     return RUN_ALL_TESTS();
878 }
879 
880 // The following sets variables for GNU EMACS
881 // Local Variables:
882 // tab-width:4
883 // End:
884