os/ossrv/genericopenlibs/posixrealtimeextensions/src/timer.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Name        : timer.cpp
    15 // Part of     : librt-timer specific cpp file
    16 // This is a project specific source file for building the 
    17 // timer related functions as part of librt library.
    18 // 
    19 //
    20 
    21 #include <e32math.h> 
    22 
    23 #include "sysif.h"
    24 #include "timer.h"
    25 #include "timerhandler.h"
    26 #include "timermessage.h"
    27 
    28 #define BOUNDARY_CHECK(rqtp) ((rqtp.tv_nsec != 0 && rqtp.tv_nsec < 1000) || \
    29 							   rqtp.tv_nsec >= 1000000000L )\
    30 
    31 //ctor
    32 static TInt64 seed = 0xdeadbeef;
    33 CRtTimer::CRtTimer(struct sigevent *aSig)
    34 	{
    35 	iTimer.Set(this);
    36 	iTimerId = Math::Rand (seed);
    37 	
    38 	if(aSig == NULL)	
    39 		{
    40 		iSigEvent.sigev_notify = SIGEV_SIGNAL;
    41 		iSigEvent.sigev_signo = SIGALRM;
    42 		}
    43 	else
    44 		{
    45 		iSigEvent = *aSig;				
    46 		}
    47 		
    48 	iIsArmed = EFalse;
    49 	}
    50 
    51 //dtor
    52 CRtTimer::~CRtTimer()
    53 	{
    54 	//should be called in context of the timer server thread.
    55 	if(iIsArmed)
    56 		{
    57 		iTimer.Cancel();	
    58 		}	
    59 	}
    60 
    61 //NewL method
    62 CRtTimer* CRtTimer::New(struct sigevent *aSig)
    63 	{
    64 	return new CRtTimer(aSig);
    65 	}
    66 
    67 //sets the timer for the given value
    68 TInt CRtTimer::SetTime(TInt aFlag, const struct itimerspec *aIpTime,
    69 			 struct itimerspec *aOpTime)
    70 	{
    71 	//Check for boundary values of seconds and microseconds
    72 	if (aIpTime == NULL || ((BOUNDARY_CHECK(aIpTime->it_value) || BOUNDARY_CHECK(aIpTime->it_interval)) &&
    73 	   (aIpTime->it_value.tv_sec != 0 || aIpTime->it_value.tv_nsec != 0)) )
    74 		{
    75 		return KErrArgument;
    76 		}
    77 		
    78 	if(aIpTime->it_value.tv_sec == 0 && aIpTime->it_value.tv_nsec == 0)
    79 		{
    80 		if(!iIsArmed)	
    81 			return KErrNone;
    82 		else
    83 			iIsTimerReset = ETrue;
    84 		}
    85 
    86 	//load the time to expiration in the output timer value.	
    87 	if(aOpTime)
    88 		{
    89 		Time(aOpTime);	
    90 		}
    91 
    92 	//start setting the timer value...
    93 	clock_gettime(CLOCK_REALTIME, &iStartTime.it_value);
    94 	
    95 	iStartTime.it_interval = aIpTime->it_interval;		
    96 	iEndTime = aIpTime->it_value;
    97 	
    98 	if((aFlag & TIMER_ABSTIME) == 0) // relative timer
    99 		{
   100 		iEndTime.tv_sec+=iStartTime.it_value.tv_sec;
   101 		iEndTime.tv_nsec+=iStartTime.it_value.tv_nsec;
   102 		}
   103 	getTimerHandler()->session.OnDemandConnect(getTimerHandler()->iServer);
   104 	TInt lRet = getTimerHandler()->session.SetTime(iTimerId);
   105 	return lRet;
   106 	}
   107 
   108 //gets the time to expiry.
   109 TInt CRtTimer::Time(struct itimerspec *aTime) const
   110 	{
   111 	TInt err = KErrNone;
   112 	if(NULL == aTime)
   113 		{
   114 		err = KErrArgument;	
   115 		}
   116 	else if (!iIsArmed)
   117 		{
   118 		memset(aTime, 0, sizeof(struct itimerspec));
   119 		}
   120 	else
   121 		{
   122 		struct timespec clktime;
   123 		clock_gettime(CLOCK_REALTIME, &clktime);
   124 		
   125 		aTime->it_value.tv_sec = iEndTime.tv_sec - clktime.tv_sec;
   126 		aTime->it_value.tv_nsec = iEndTime.tv_nsec - clktime.tv_nsec;	
   127 		aTime->it_interval = iStartTime.it_interval;				
   128 		}	
   129 		
   130 	return err;	
   131 	}
   132 
   133 //gets the overruns for this timer
   134 TInt CRtTimer::OverrunCount(TInt& aOverrunCount) const
   135 	{
   136 #if (!defined SYMBIAN_OE_POSIX_SIGNALS || !defined SYMBIAN_OE_LIBRT)
   137 	aOverrunCount = aOverrunCount;//warning fix
   138 	return KErrNotSupported;	
   139 
   140 #else
   141 	aOverrunCount = Backend()->Overrun(iTimerId);
   142 	if(aOverrunCount >= DELAYTIMER_MAX)
   143 		aOverrunCount = DELAYTIMER_MAX;
   144 	
   145 	return KErrNone;
   146 #endif
   147 	}
   148 //EOF
   149