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 */
printUString(const::rtl::OUString & str)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 */
printBool(sal_Bool bOk)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 {
thread_sleep(sal_Int32 _nSec)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 }
thread_sleep_tenth_sec(sal_Int32 _nTenthSec)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:
IncreaseThread(struct resource * pData)113 IncreaseThread( struct resource *pData ): pResource( pData ) { }
114
~IncreaseThread()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
run()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:
DecreaseThread(struct resource * pData)141 DecreaseThread( struct resource *pData ): pResource( pData ) { }
142
~DecreaseThread()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
run()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
PutThread(struct chain * pData)179 PutThread( struct chain* pData ): pChain( pData ) { }
180
~PutThread()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
run()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
HoldThread(Mutex * pMutex)217 HoldThread( Mutex* pMutex ): pMyMutex( pMutex ) { }
218
~HoldThread()219 ~HoldThread( )
220 {
221 CPPUNIT_ASSERT_MESSAGE( "#HoldThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
222 }
223 protected:
224 Mutex* pMyMutex;
225
run()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
WaitThread(Mutex * pMutex)239 WaitThread( Mutex* pMutex ): pMyMutex( pMutex ) { }
240
~WaitThread()241 ~WaitThread( )
242 {
243 CPPUNIT_ASSERT_MESSAGE( "#WaitThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
244 }
245 protected:
246 Mutex* pMyMutex;
247
run()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
GlobalMutexThread()263 GlobalMutexThread( ){ }
264
~GlobalMutexThread()265 ~GlobalMutexThread( )
266 {
267 CPPUNIT_ASSERT_MESSAGE( "#GlobalMutexThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
268 }
269 protected:
run()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
setUp()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
tearDown()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 */
ctor_001()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 */
ctor_002()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.
acquire_001()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
acquire_002()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
tryToAcquire_001()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 */
release_001()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?
release_002()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.
getGlobalMutex_001()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
getGlobalMutex_002()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
GuardThread(Mutex * pMutex)597 GuardThread( Mutex* pMutex ): pMyMutex( pMutex ) { }
598
~GuardThread()599 ~GuardThread( )
600 {
601 CPPUNIT_ASSERT_MESSAGE( "#GuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
602 }
603 protected:
604 Mutex* pMyMutex;
605
run()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.
ctor_001()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
ctor_002()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
ClearGuardThread(Mutex * pMutex)683 ClearGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {}
684
~ClearGuardThread()685 ~ClearGuardThread( )
686 {
687 CPPUNIT_ASSERT_MESSAGE( "#ClearGuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
688 }
689 protected:
690 Mutex* pMyMutex;
691
run()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:
ctor_001()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
ctor_002()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:
clear_001()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
clear_002()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
ResetGuardThread(Mutex * pMutex)825 ResetGuardThread( Mutex* pMutex ): pMyMutex( pMutex ) {}
826
~ResetGuardThread()827 ~ResetGuardThread( )
828 {
829 CPPUNIT_ASSERT_MESSAGE( "#ResetGuardThread does not shutdown properly.\n", sal_False == this -> isRunning( ) );
830 }
831 protected:
832 Mutex* pMyMutex;
833
run()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:
ctor_001()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
ctor_002()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:
reset_001()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
reset_002()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