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