LCOV - code coverage report
Current view: top level - libreoffice/sal/qa/osl/mutex - osl_Mutex.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 75 397 18.9 %
Date: 2012-12-27 Functions: 23 127 18.1 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.10