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