xref: /trunk/main/sal/qa/osl/mutex/osl_Mutex.cxx (revision 79aad27f)
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 aquire 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 aquire, 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, aquire 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 aquire 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 aquire 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 aquire 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 aquire 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 aquire, 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