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