LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/vcl/source/app - timer.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 161 164 98.2 %
Date: 2013-07-09 Functions: 17 17 100.0 %
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 <tools/time.hxx>
      22             : 
      23             : #include <vcl/svapp.hxx>
      24             : #include <vcl/timer.hxx>
      25             : 
      26             : #include <saltimer.hxx>
      27             : #include <svdata.hxx>
      28             : #include <salinst.hxx>
      29             : 
      30             : 
      31             : // =======================================================================
      32             : 
      33             : #define MAX_TIMER_PERIOD    ((sal_uLong)0xFFFFFFFF)
      34             : 
      35             : // ---------------------
      36             : // - TimeManager-Types -
      37             : // ---------------------
      38             : 
      39             : struct ImplTimerData
      40             : {
      41             :     ImplTimerData*  mpNext;         // Pointer to the next Instance
      42             :     Timer*          mpSVTimer;      // Pointer to SV Timer instance
      43             :     sal_uLong           mnUpdateTime;   // Last Update Time
      44             :     sal_uLong           mnTimerUpdate;  // TimerCallbackProcs on stack
      45             :     bool            mbDelete;       // Was timer deleted during Update()?
      46             :     bool            mbInTimeout;    // Are we in a timeout handler?
      47             : };
      48             : 
      49             : // =======================================================================
      50             : 
      51          94 : void Timer::ImplDeInitTimer()
      52             : {
      53          94 :     ImplSVData*     pSVData = ImplGetSVData();
      54          94 :     ImplTimerData*  pTimerData = pSVData->mpFirstTimerData;
      55             : 
      56          94 :     if ( pTimerData )
      57             :     {
      58         195 :         do
      59             :         {
      60         195 :             ImplTimerData* pTempTimerData = pTimerData;
      61         195 :             if ( pTimerData->mpSVTimer )
      62             :             {
      63          73 :                 pTimerData->mpSVTimer->mbActive = sal_False;
      64          73 :                 pTimerData->mpSVTimer->mpTimerData = NULL;
      65             :             }
      66         195 :             pTimerData = pTimerData->mpNext;
      67         195 :             delete pTempTimerData;
      68             :         }
      69             :         while ( pTimerData );
      70             : 
      71          94 :         pSVData->mpFirstTimerData   = NULL;
      72          94 :         pSVData->mnTimerPeriod      = 0;
      73          94 :         delete pSVData->mpSalTimer;
      74          94 :         pSVData->mpSalTimer = NULL;
      75             :     }
      76          94 : }
      77             : 
      78             : // -----------------------------------------------------------------------
      79             : 
      80       27618 : static void ImplStartTimer( ImplSVData* pSVData, sal_uLong nMS )
      81             : {
      82       27618 :     if ( !nMS )
      83        1511 :         nMS = 1;
      84             : 
      85       27618 :     if ( nMS != pSVData->mnTimerPeriod )
      86             :     {
      87       22876 :         pSVData->mnTimerPeriod = nMS;
      88       22876 :         pSVData->mpSalTimer->Start( nMS );
      89             :     }
      90       27618 : }
      91             : 
      92             : // -----------------------------------------------------------------------
      93             : 
      94       16965 : void Timer::ImplTimerCallbackProc()
      95             : {
      96       16965 :     ImplSVData*     pSVData = ImplGetSVData();
      97             :     ImplTimerData*  pTimerData;
      98             :     ImplTimerData*  pPrevTimerData;
      99       16965 :     sal_uLong           nMinPeriod = MAX_TIMER_PERIOD;
     100             :     sal_uLong           nDeltaTime;
     101       16965 :     sal_uLong           nTime = Time::GetSystemTicks();
     102             : 
     103       16965 :     if ( pSVData->mbNoCallTimer )
     104       16965 :         return;
     105             : 
     106       16965 :     pSVData->mnTimerUpdate++;
     107       16965 :     pSVData->mbNotAllTimerCalled = sal_True;
     108             : 
     109             :     // find timer where the timer handler needs to be called
     110       16965 :     pTimerData = pSVData->mpFirstTimerData;
     111      146752 :     while ( pTimerData )
     112             :     {
     113             :         // If the timer is not new, was not deleted, and if it is not in the timeout handler, then
     114             :         // call the handler as soon as the time is up.
     115      221784 :         if ( (pTimerData->mnTimerUpdate < pSVData->mnTimerUpdate) &&
     116      205577 :              !pTimerData->mbDelete && !pTimerData->mbInTimeout )
     117             :         {
     118             :             // time has expired
     119       96615 :             if ( (pTimerData->mnUpdateTime+pTimerData->mpSVTimer->mnTimeout) <= nTime )
     120             :             {
     121             :                 // set new update time
     122       27983 :                 pTimerData->mnUpdateTime = nTime;
     123             : 
     124             :                 // if no AutoTimer than stop
     125       27983 :                 if ( !pTimerData->mpSVTimer->mbAuto )
     126             :                 {
     127       21168 :                     pTimerData->mpSVTimer->mbActive = sal_False;
     128       21168 :                     pTimerData->mbDelete = true;
     129             :                 }
     130             : 
     131             :                 // call Timeout
     132       27983 :                 pTimerData->mbInTimeout = true;
     133       27983 :                 pTimerData->mpSVTimer->Timeout();
     134       27983 :                 pTimerData->mbInTimeout = false;
     135             :             }
     136             :         }
     137             : 
     138      112822 :         pTimerData = pTimerData->mpNext;
     139             :     }
     140             : 
     141             :     // determine new time
     142       16965 :     sal_uLong nNewTime = Time::GetSystemTicks();
     143       16965 :     pPrevTimerData = NULL;
     144       16965 :     pTimerData = pSVData->mpFirstTimerData;
     145      146752 :     while ( pTimerData )
     146             :     {
     147             :         // ignore if timer is still in timeout handler
     148      112822 :         if ( pTimerData->mbInTimeout )
     149             :         {
     150           0 :             pPrevTimerData = pTimerData;
     151           0 :             pTimerData = pTimerData->mpNext;
     152             :         }
     153             :         // Was timer destroyed in the meantime?
     154      112822 :         else if ( pTimerData->mbDelete )
     155             :         {
     156       28867 :             if ( pPrevTimerData )
     157       28644 :                 pPrevTimerData->mpNext = pTimerData->mpNext;
     158             :             else
     159         223 :                 pSVData->mpFirstTimerData = pTimerData->mpNext;
     160       28867 :             if ( pTimerData->mpSVTimer )
     161       17052 :                 pTimerData->mpSVTimer->mpTimerData = NULL;
     162       28867 :             ImplTimerData* pTempTimerData = pTimerData;
     163       28867 :             pTimerData = pTimerData->mpNext;
     164       28867 :             delete pTempTimerData;
     165             :         }
     166             :         else
     167             :         {
     168       83955 :             pTimerData->mnTimerUpdate = 0;
     169             :             // determine smallest time slot
     170       83955 :             if ( pTimerData->mnUpdateTime == nTime )
     171             :             {
     172        9500 :                 nDeltaTime = pTimerData->mpSVTimer->mnTimeout;
     173        9500 :                 if ( nDeltaTime < nMinPeriod )
     174        6267 :                     nMinPeriod = nDeltaTime;
     175             :             }
     176             :             else
     177             :             {
     178       74455 :                 nDeltaTime = pTimerData->mnUpdateTime + pTimerData->mpSVTimer->mnTimeout;
     179       74455 :                 if ( nDeltaTime < nNewTime )
     180        9989 :                     nMinPeriod = 1;
     181             :                 else
     182             :                 {
     183       64466 :                     nDeltaTime -= nNewTime;
     184       64466 :                     if ( nDeltaTime < nMinPeriod )
     185       33282 :                         nMinPeriod = nDeltaTime;
     186             :                 }
     187             :             }
     188       83955 :             pPrevTimerData = pTimerData;
     189       83955 :             pTimerData = pTimerData->mpNext;
     190             :         }
     191             :     }
     192             : 
     193             :     // delete clock if no more timers available
     194       16965 :     if ( !pSVData->mpFirstTimerData )
     195             :     {
     196          50 :         pSVData->mpSalTimer->Stop();
     197          50 :         pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
     198             :     }
     199             :     else
     200       16915 :         ImplStartTimer( pSVData, nMinPeriod );
     201             : 
     202       16965 :     pSVData->mnTimerUpdate--;
     203       16965 :     pSVData->mbNotAllTimerCalled = sal_False;
     204             : }
     205             : 
     206             : // =======================================================================
     207             : 
     208      170786 : Timer::Timer()
     209             : {
     210      170786 :     mpTimerData     = NULL;
     211      170786 :     mnTimeout       = 1;
     212      170786 :     mbAuto          = sal_False;
     213      170786 :     mbActive        = sal_False;
     214      170786 : }
     215             : 
     216             : // -----------------------------------------------------------------------
     217             : 
     218         417 : Timer::Timer( const Timer& rTimer )
     219             : {
     220         417 :     mpTimerData     = NULL;
     221         417 :     mnTimeout       = rTimer.mnTimeout;
     222         417 :     mbAuto          = sal_False;
     223         417 :     mbActive        = sal_False;
     224         417 :     maTimeoutHdl    = rTimer.maTimeoutHdl;
     225             : 
     226         417 :     if ( rTimer.IsActive() )
     227          38 :         Start();
     228         417 : }
     229             : 
     230             : // -----------------------------------------------------------------------
     231             : 
     232      172149 : Timer::~Timer()
     233             : {
     234      170103 :     if ( mpTimerData )
     235             :     {
     236       13219 :         mpTimerData->mbDelete = true;
     237       13219 :         mpTimerData->mpSVTimer = NULL;
     238             :     }
     239      172149 : }
     240             : 
     241             : // -----------------------------------------------------------------------
     242             : 
     243       25913 : void Timer::Timeout()
     244             : {
     245       25913 :     maTimeoutHdl.Call( this );
     246       25913 : }
     247             : 
     248             : // -----------------------------------------------------------------------
     249             : 
     250      227531 : void Timer::SetTimeout( sal_uLong nNewTimeout )
     251             : {
     252      227531 :     mnTimeout = nNewTimeout;
     253             : 
     254             :     // if timer is active then renew clock
     255      227531 :     if ( mbActive )
     256             :     {
     257        8171 :         ImplSVData* pSVData = ImplGetSVData();
     258        8171 :         if ( !pSVData->mnTimerUpdate && (mnTimeout < pSVData->mnTimerPeriod) )
     259           0 :             ImplStartTimer( pSVData, mnTimeout );
     260             :     }
     261      227531 : }
     262             : 
     263             : // -----------------------------------------------------------------------
     264             : 
     265      491228 : void Timer::Start()
     266             : {
     267      491228 :     mbActive = sal_True;
     268             : 
     269      491228 :     ImplSVData* pSVData = ImplGetSVData();
     270      491228 :     if ( !mpTimerData )
     271             :     {
     272       30575 :         if ( !pSVData->mpFirstTimerData )
     273             :         {
     274         183 :             pSVData->mnTimerPeriod = MAX_TIMER_PERIOD;
     275         183 :             if( ! pSVData->mpSalTimer )
     276             :             {
     277         133 :                 pSVData->mpSalTimer = pSVData->mpDefInst->CreateSalTimer();
     278         133 :                 pSVData->mpSalTimer->SetCallback( ImplTimerCallbackProc );
     279             :             }
     280             :         }
     281             : 
     282             :         // insert timer and start
     283       30575 :         mpTimerData                 = new ImplTimerData;
     284       30575 :         mpTimerData->mpSVTimer      = this;
     285       30575 :         mpTimerData->mnUpdateTime   = Time::GetSystemTicks();
     286       30575 :         mpTimerData->mnTimerUpdate  = pSVData->mnTimerUpdate;
     287       30575 :         mpTimerData->mbDelete       = false;
     288       30575 :         mpTimerData->mbInTimeout    = false;
     289             : 
     290             :         // insert last due to SFX!
     291       30575 :         ImplTimerData* pPrev = NULL;
     292       30575 :         ImplTimerData* pData = pSVData->mpFirstTimerData;
     293      712621 :         while ( pData )
     294             :         {
     295      651471 :             pPrev = pData;
     296      651471 :             pData = pData->mpNext;
     297             :         }
     298       30575 :         mpTimerData->mpNext = NULL;
     299       30575 :         if ( pPrev )
     300       30392 :             pPrev->mpNext = mpTimerData;
     301             :         else
     302         183 :             pSVData->mpFirstTimerData = mpTimerData;
     303             : 
     304       30575 :         if ( mnTimeout < pSVData->mnTimerPeriod )
     305       10703 :             ImplStartTimer( pSVData, mnTimeout );
     306             :     }
     307      460653 :     else if( !mpTimerData->mpSVTimer ) // TODO: remove when guilty found
     308             :     {
     309             :         OSL_FAIL( "Timer::Start() on a destroyed Timer!" );
     310             :     }
     311             :     else
     312             :     {
     313      460653 :         mpTimerData->mnUpdateTime    = Time::GetSystemTicks();
     314      460653 :         mpTimerData->mnTimerUpdate   = pSVData->mnTimerUpdate;
     315      460653 :         mpTimerData->mbDelete        = false;
     316             :     }
     317      491228 : }
     318             : 
     319             : // -----------------------------------------------------------------------
     320             : 
     321      350182 : void Timer::Stop()
     322             : {
     323      350182 :     mbActive = sal_False;
     324             : 
     325      350182 :     if ( mpTimerData )
     326      153277 :         mpTimerData->mbDelete = true;
     327      350182 : }
     328             : 
     329             : // -----------------------------------------------------------------------
     330             : 
     331          49 : Timer& Timer::operator=( const Timer& rTimer )
     332             : {
     333          49 :     if ( IsActive() )
     334          12 :         Stop();
     335             : 
     336          49 :     mbActive        = sal_False;
     337          49 :     mnTimeout       = rTimer.mnTimeout;
     338          49 :     maTimeoutHdl    = rTimer.maTimeoutHdl;
     339             : 
     340          49 :     if ( rTimer.IsActive() )
     341          14 :         Start();
     342             : 
     343          49 :     return *this;
     344             : }
     345             : 
     346             : // =======================================================================
     347             : 
     348       11987 : AutoTimer::AutoTimer()
     349             : {
     350       11987 :     mbAuto = sal_True;
     351       11987 : }
     352             : 
     353             : // -----------------------------------------------------------------------
     354             : 
     355         417 : AutoTimer::AutoTimer( const AutoTimer& rTimer ) : Timer( rTimer )
     356             : {
     357         417 :     mbAuto = sal_True;
     358         417 : }
     359             : 
     360             : // -----------------------------------------------------------------------
     361             : 
     362          49 : AutoTimer& AutoTimer::operator=( const AutoTimer& rTimer )
     363             : {
     364          49 :     Timer::operator=( rTimer );
     365          49 :     return *this;
     366         465 : }
     367             : 
     368             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10