LCOV - code coverage report
Current view: top level - vcl/source/app - timer.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 160 163 98.2 %
Date: 2012-08-25 Functions: 15 15 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 70 78 89.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <tools/time.hxx>
      31                 :            : 
      32                 :            : #include <vcl/svapp.hxx>
      33                 :            : #include <vcl/timer.hxx>
      34                 :            : 
      35                 :            : #include <saltimer.hxx>
      36                 :            : #include <svdata.hxx>
      37                 :            : #include <salinst.hxx>
      38                 :            : 
      39                 :            : 
      40                 :            : // =======================================================================
      41                 :            : 
      42                 :            : #define MAX_TIMER_PERIOD    ((sal_uLong)0xFFFFFFFF)
      43                 :            : 
      44                 :            : // ---------------------
      45                 :            : // - TimeManager-Types -
      46                 :            : // ---------------------
      47                 :            : 
      48                 :            : struct ImplTimerData
      49                 :            : {
      50                 :            :     ImplTimerData*  mpNext;         // Pointer to the next Instance
      51                 :            :     Timer*          mpSVTimer;      // Pointer to SV Timer instance
      52                 :            :     sal_uLong           mnUpdateTime;   // Last Update Time
      53                 :            :     sal_uLong           mnTimerUpdate;  // TimerCallbackProcs on stack
      54                 :            :     sal_Bool            mbDelete;       // Was timer deleted during Update()?
      55                 :            :     sal_Bool            mbInTimeout;    // Are we in a timeout handler?
      56                 :            : };
      57                 :            : 
      58                 :            : // =======================================================================
      59                 :            : 
      60                 :        158 : void Timer::ImplDeInitTimer()
      61                 :            : {
      62                 :        158 :     ImplSVData*     pSVData = ImplGetSVData();
      63                 :        158 :     ImplTimerData*  pTimerData = pSVData->mpFirstTimerData;
      64                 :            : 
      65         [ +  - ]:        158 :     if ( pTimerData )
      66                 :            :     {
      67         [ +  + ]:        362 :         do
      68                 :            :         {
      69                 :        362 :             ImplTimerData* pTempTimerData = pTimerData;
      70         [ +  + ]:        362 :             if ( pTimerData->mpSVTimer )
      71                 :            :             {
      72                 :        155 :                 pTimerData->mpSVTimer->mbActive = sal_False;
      73                 :        155 :                 pTimerData->mpSVTimer->mpTimerData = NULL;
      74                 :            :             }
      75                 :        362 :             pTimerData = pTimerData->mpNext;
      76                 :        362 :             delete pTempTimerData;
      77                 :            :         }
      78                 :            :         while ( pTimerData );
      79                 :            : 
      80                 :        158 :         pSVData->mpFirstTimerData   = NULL;
      81                 :        158 :         pSVData->mnTimerPeriod      = 0;
      82         [ +  - ]:        158 :         delete pSVData->mpSalTimer;
      83                 :        158 :         pSVData->mpSalTimer = NULL;
      84                 :            :     }
      85                 :        158 : }
      86                 :            : 
      87                 :            : // -----------------------------------------------------------------------
      88                 :            : 
      89                 :      52609 : static void ImplStartTimer( ImplSVData* pSVData, sal_uLong nMS )
      90                 :            : {
      91         [ +  + ]:      52609 :     if ( !nMS )
      92                 :       2602 :         nMS = 1;
      93                 :            : 
      94         [ +  + ]:      52609 :     if ( nMS != pSVData->mnTimerPeriod )
      95                 :            :     {
      96                 :      43475 :         pSVData->mnTimerPeriod = nMS;
      97                 :      43475 :         pSVData->mpSalTimer->Start( nMS );
      98                 :            :     }
      99                 :      52609 : }
     100                 :            : 
     101                 :            : // -----------------------------------------------------------------------
     102                 :            : 
     103                 :      33012 : void Timer::ImplTimerCallbackProc()
     104                 :            : {
     105                 :      33012 :     ImplSVData*     pSVData = ImplGetSVData();
     106                 :            :     ImplTimerData*  pTimerData;
     107                 :            :     ImplTimerData*  pPrevTimerData;
     108                 :      33012 :     sal_uLong           nMinPeriod = MAX_TIMER_PERIOD;
     109                 :            :     sal_uLong           nDeltaTime;
     110                 :      33012 :     sal_uLong           nTime = Time::GetSystemTicks();
     111                 :            : 
     112         [ -  + ]:      33012 :     if ( pSVData->mbNoCallTimer )
     113                 :      33012 :         return;
     114                 :            : 
     115                 :      33012 :     pSVData->mnTimerUpdate++;
     116                 :      33012 :     pSVData->mbNotAllTimerCalled = sal_True;
     117                 :            : 
     118                 :            :     // find timer where the timer handler needs to be called
     119                 :      33012 :     pTimerData = pSVData->mpFirstTimerData;
     120         [ +  + ]:     266061 :     while ( pTimerData )
     121                 :            :     {
     122                 :            :         // If the timer is not new, was not deleted, and if it is not in the timeout handler, then
     123                 :            :         // call the handler as soon as the time is up.
     124 [ +  + ][ +  + ]:     233049 :         if ( (pTimerData->mnTimerUpdate < pSVData->mnTimerUpdate) &&
                 [ +  - ]
     125                 :     433423 :              !pTimerData->mbDelete && !pTimerData->mbInTimeout )
     126                 :            :         {
     127                 :            :             // time has expired
     128         [ +  + ]:     206662 :             if ( (pTimerData->mnUpdateTime+pTimerData->mpSVTimer->mnTimeout) <= nTime )
     129                 :            :             {
     130                 :            :                 // set new update time
     131                 :      58935 :                 pTimerData->mnUpdateTime = nTime;
     132                 :            : 
     133                 :            :                 // if no AutoTimer than stop
     134         [ +  + ]:      58935 :                 if ( !pTimerData->mpSVTimer->mbAuto )
     135                 :            :                 {
     136                 :      45528 :                     pTimerData->mpSVTimer->mbActive = sal_False;
     137                 :      45528 :                     pTimerData->mbDelete = sal_True;
     138                 :            :                 }
     139                 :            : 
     140                 :            :                 // call Timeout
     141                 :      58935 :                 pTimerData->mbInTimeout = sal_True;
     142                 :      58935 :                 pTimerData->mpSVTimer->Timeout();
     143                 :      58935 :                 pTimerData->mbInTimeout = sal_False;
     144                 :            :             }
     145                 :            :         }
     146                 :            : 
     147                 :     233049 :         pTimerData = pTimerData->mpNext;
     148                 :            :     }
     149                 :            : 
     150                 :            :     // determine new time
     151                 :      33012 :     sal_uLong nNewTime = Time::GetSystemTicks();
     152                 :      33012 :     pPrevTimerData = NULL;
     153                 :      33012 :     pTimerData = pSVData->mpFirstTimerData;
     154         [ +  + ]:     266061 :     while ( pTimerData )
     155                 :            :     {
     156                 :            :         // ignore if timer is still in timeout handler
     157         [ -  + ]:     233049 :         if ( pTimerData->mbInTimeout )
     158                 :            :         {
     159                 :          0 :             pPrevTimerData = pTimerData;
     160                 :          0 :             pTimerData = pTimerData->mpNext;
     161                 :            :         }
     162                 :            :         // Was timer destroyed in the meantime?
     163         [ +  + ]:     233049 :         else if ( pTimerData->mbDelete )
     164                 :            :         {
     165         [ +  + ]:      50039 :             if ( pPrevTimerData )
     166                 :      49611 :                 pPrevTimerData->mpNext = pTimerData->mpNext;
     167                 :            :             else
     168                 :        428 :                 pSVData->mpFirstTimerData = pTimerData->mpNext;
     169         [ +  + ]:      50039 :             if ( pTimerData->mpSVTimer )
     170                 :      32535 :                 pTimerData->mpSVTimer->mpTimerData = NULL;
     171                 :      50039 :             ImplTimerData* pTempTimerData = pTimerData;
     172                 :      50039 :             pTimerData = pTimerData->mpNext;
     173                 :      50039 :             delete pTempTimerData;
     174                 :            :         }
     175                 :            :         else
     176                 :            :         {
     177                 :     183010 :             pTimerData->mnTimerUpdate = 0;
     178                 :            :             // determine smallest time slot
     179         [ +  + ]:     183010 :             if ( pTimerData->mnUpdateTime == nTime )
     180                 :            :             {
     181                 :      19301 :                 nDeltaTime = pTimerData->mpSVTimer->mnTimeout;
     182         [ +  + ]:      19301 :                 if ( nDeltaTime < nMinPeriod )
     183                 :      12117 :                     nMinPeriod = nDeltaTime;
     184                 :            :             }
     185                 :            :             else
     186                 :            :             {
     187                 :     163709 :                 nDeltaTime = pTimerData->mnUpdateTime + pTimerData->mpSVTimer->mnTimeout;
     188         [ +  + ]:     163709 :                 if ( nDeltaTime < nNewTime )
     189                 :      22364 :                     nMinPeriod = 1;
     190                 :            :                 else
     191                 :            :                 {
     192                 :     141345 :                     nDeltaTime -= nNewTime;
     193         [ +  + ]:     141345 :                     if ( nDeltaTime < nMinPeriod )
     194                 :      79630 :                         nMinPeriod = nDeltaTime;
     195                 :            :                 }
     196                 :            :             }
     197                 :     183010 :             pPrevTimerData = pTimerData;
     198                 :     183010 :             pTimerData = pTimerData->mpNext;
     199                 :            :         }
     200                 :            :     }
     201                 :            : 
     202                 :            :     // delete clock if no more timers available
     203         [ +  + ]:      33012 :     if ( !pSVData->mpFirstTimerData )
     204                 :            :     {
     205                 :         93 :         pSVData->mpSalTimer->Stop();
     206                 :         93 :         pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
     207                 :            :     }
     208                 :            :     else
     209                 :      32919 :         ImplStartTimer( pSVData, nMinPeriod );
     210                 :            : 
     211                 :      33012 :     pSVData->mnTimerUpdate--;
     212                 :      33012 :     pSVData->mbNotAllTimerCalled = sal_False;
     213                 :            : }
     214                 :            : 
     215                 :            : // =======================================================================
     216                 :            : 
     217                 :     280561 : Timer::Timer()
     218                 :            : {
     219                 :     280561 :     mpTimerData     = NULL;
     220                 :     280561 :     mnTimeout       = 1;
     221                 :     280561 :     mbAuto          = sal_False;
     222                 :     280561 :     mbActive        = sal_False;
     223                 :     280561 : }
     224                 :            : 
     225                 :            : // -----------------------------------------------------------------------
     226                 :            : 
     227                 :        602 : Timer::Timer( const Timer& rTimer )
     228                 :            : {
     229                 :        602 :     mpTimerData     = NULL;
     230                 :        602 :     mnTimeout       = rTimer.mnTimeout;
     231                 :        602 :     mbAuto          = sal_False;
     232                 :        602 :     mbActive        = sal_False;
     233                 :        602 :     maTimeoutHdl    = rTimer.maTimeoutHdl;
     234                 :            : 
     235         [ +  + ]:        602 :     if ( rTimer.IsActive() )
     236                 :         44 :         Start();
     237                 :        602 : }
     238                 :            : 
     239                 :            : // -----------------------------------------------------------------------
     240                 :            : 
     241                 :     278941 : Timer::~Timer()
     242                 :            : {
     243         [ +  + ]:     275575 :     if ( mpTimerData )
     244                 :            :     {
     245                 :      20105 :         mpTimerData->mbDelete = sal_True;
     246                 :      20105 :         mpTimerData->mpSVTimer = NULL;
     247                 :            :     }
     248         [ -  + ]:     278941 : }
     249                 :            : 
     250                 :            : // -----------------------------------------------------------------------
     251                 :            : 
     252                 :      54392 : void Timer::Timeout()
     253                 :            : {
     254                 :      54392 :     maTimeoutHdl.Call( this );
     255                 :      54392 : }
     256                 :            : 
     257                 :            : // -----------------------------------------------------------------------
     258                 :            : 
     259                 :     377160 : void Timer::SetTimeout( sal_uLong nNewTimeout )
     260                 :            : {
     261                 :     377160 :     mnTimeout = nNewTimeout;
     262                 :            : 
     263                 :            :     // if timer is active then renew clock
     264         [ +  + ]:     377160 :     if ( mbActive )
     265                 :            :     {
     266                 :      14144 :         ImplSVData* pSVData = ImplGetSVData();
     267 [ -  + ][ +  + ]:      14144 :         if ( !pSVData->mnTimerUpdate && (mnTimeout < pSVData->mnTimerPeriod) )
     268                 :          0 :             ImplStartTimer( pSVData, mnTimeout );
     269                 :            :     }
     270                 :     377160 : }
     271                 :            : 
     272                 :            : // -----------------------------------------------------------------------
     273                 :            : 
     274                 :     265979 : void Timer::Start()
     275                 :            : {
     276                 :     265979 :     mbActive = sal_True;
     277                 :            : 
     278                 :     265979 :     ImplSVData* pSVData = ImplGetSVData();
     279         [ +  + ]:     265979 :     if ( !mpTimerData )
     280                 :            :     {
     281         [ +  + ]:      53263 :         if ( !pSVData->mpFirstTimerData )
     282                 :            :         {
     283                 :        326 :             pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
     284         [ +  + ]:        326 :             if( ! pSVData->mpSalTimer )
     285                 :            :             {
     286                 :        233 :                 pSVData->mpSalTimer = pSVData->mpDefInst->CreateSalTimer();
     287                 :        233 :                 pSVData->mpSalTimer->SetCallback( ImplTimerCallbackProc );
     288                 :            :             }
     289                 :            :         }
     290                 :            : 
     291                 :            :         // insert timer and start
     292                 :      53263 :         mpTimerData                 = new ImplTimerData;
     293                 :      53263 :         mpTimerData->mpSVTimer      = this;
     294                 :      53263 :         mpTimerData->mnUpdateTime   = Time::GetSystemTicks();
     295                 :      53263 :         mpTimerData->mnTimerUpdate  = pSVData->mnTimerUpdate;
     296                 :      53263 :         mpTimerData->mbDelete       = sal_False;
     297                 :      53263 :         mpTimerData->mbInTimeout    = sal_False;
     298                 :            : 
     299                 :            :         // insert last due to SFX!
     300                 :      53263 :         ImplTimerData* pPrev = NULL;
     301                 :      53263 :         ImplTimerData* pData = pSVData->mpFirstTimerData;
     302         [ +  + ]:     722919 :         while ( pData )
     303                 :            :         {
     304                 :     669656 :             pPrev = pData;
     305                 :     669656 :             pData = pData->mpNext;
     306                 :            :         }
     307                 :      53263 :         mpTimerData->mpNext = NULL;
     308         [ +  + ]:      53263 :         if ( pPrev )
     309                 :      52937 :             pPrev->mpNext = mpTimerData;
     310                 :            :         else
     311                 :        326 :             pSVData->mpFirstTimerData = mpTimerData;
     312                 :            : 
     313         [ +  + ]:      53263 :         if ( mnTimeout < pSVData->mnTimerPeriod )
     314                 :      19690 :             ImplStartTimer( pSVData, mnTimeout );
     315                 :            :     }
     316         [ +  - ]:     212716 :     else if( !mpTimerData->mpSVTimer ) // TODO: remove when guilty found
     317                 :            :     {
     318                 :            :         OSL_FAIL( "Timer::Start() on a destroyed Timer!" );
     319                 :            :     }
     320                 :            :     else
     321                 :            :     {
     322                 :     212716 :         mpTimerData->mnUpdateTime    = Time::GetSystemTicks();
     323                 :     212716 :         mpTimerData->mnTimerUpdate   = pSVData->mnTimerUpdate;
     324                 :     212716 :         mpTimerData->mbDelete        = sal_False;
     325                 :            :     }
     326                 :     265979 : }
     327                 :            : 
     328                 :            : // -----------------------------------------------------------------------
     329                 :            : 
     330                 :     596196 : void Timer::Stop()
     331                 :            : {
     332                 :     596196 :     mbActive = sal_False;
     333                 :            : 
     334         [ +  + ]:     596196 :     if ( mpTimerData )
     335                 :     261291 :         mpTimerData->mbDelete = sal_True;
     336                 :     596196 : }
     337                 :            : 
     338                 :            : // -----------------------------------------------------------------------
     339                 :            : 
     340                 :         48 : Timer& Timer::operator=( const Timer& rTimer )
     341                 :            : {
     342         [ +  + ]:         48 :     if ( IsActive() )
     343                 :         14 :         Stop();
     344                 :            : 
     345                 :         48 :     mbActive        = sal_False;
     346                 :         48 :     mnTimeout       = rTimer.mnTimeout;
     347                 :         48 :     maTimeoutHdl    = rTimer.maTimeoutHdl;
     348                 :            : 
     349         [ +  + ]:         48 :     if ( rTimer.IsActive() )
     350                 :         16 :         Start();
     351                 :            : 
     352                 :         48 :     return *this;
     353                 :            : }
     354                 :            : 
     355                 :            : // =======================================================================
     356                 :            : 
     357                 :      19681 : AutoTimer::AutoTimer()
     358                 :            : {
     359                 :      19681 :     mbAuto = sal_True;
     360                 :      19681 : }
     361                 :            : 
     362                 :            : // -----------------------------------------------------------------------
     363                 :            : 
     364                 :        602 : AutoTimer::AutoTimer( const AutoTimer& rTimer ) : Timer( rTimer )
     365                 :            : {
     366                 :        602 :     mbAuto = sal_True;
     367                 :        602 : }
     368                 :            : 
     369                 :            : // -----------------------------------------------------------------------
     370                 :            : 
     371                 :         48 : AutoTimer& AutoTimer::operator=( const AutoTimer& rTimer )
     372                 :            : {
     373                 :         48 :     Timer::operator=( rTimer );
     374                 :         48 :     return *this;
     375                 :            : }
     376                 :            : 
     377                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10