diff -r 000000000000 -r e4d67989cc36 genericopenlibs/posixrealtimeextensions/src/timer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericopenlibs/posixrealtimeextensions/src/timer.cpp Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,149 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Name : timer.cpp +// Part of : librt-timer specific cpp file +// This is a project specific source file for building the +// timer related functions as part of librt library. +// +// + +#include + +#include "sysif.h" +#include "timer.h" +#include "timerhandler.h" +#include "timermessage.h" + +#define BOUNDARY_CHECK(rqtp) ((rqtp.tv_nsec != 0 && rqtp.tv_nsec < 1000) || \ + rqtp.tv_nsec >= 1000000000L )\ + +//ctor +static TInt64 seed = 0xdeadbeef; +CRtTimer::CRtTimer(struct sigevent *aSig) + { + iTimer.Set(this); + iTimerId = Math::Rand (seed); + + if(aSig == NULL) + { + iSigEvent.sigev_notify = SIGEV_SIGNAL; + iSigEvent.sigev_signo = SIGALRM; + } + else + { + iSigEvent = *aSig; + } + + iIsArmed = EFalse; + } + +//dtor +CRtTimer::~CRtTimer() + { + //should be called in context of the timer server thread. + if(iIsArmed) + { + iTimer.Cancel(); + } + } + +//NewL method +CRtTimer* CRtTimer::New(struct sigevent *aSig) + { + return new CRtTimer(aSig); + } + +//sets the timer for the given value +TInt CRtTimer::SetTime(TInt aFlag, const struct itimerspec *aIpTime, + struct itimerspec *aOpTime) + { + //Check for boundary values of seconds and microseconds + if (aIpTime == NULL || ((BOUNDARY_CHECK(aIpTime->it_value) || BOUNDARY_CHECK(aIpTime->it_interval)) && + (aIpTime->it_value.tv_sec != 0 || aIpTime->it_value.tv_nsec != 0)) ) + { + return KErrArgument; + } + + if(aIpTime->it_value.tv_sec == 0 && aIpTime->it_value.tv_nsec == 0) + { + if(!iIsArmed) + return KErrNone; + else + iIsTimerReset = ETrue; + } + + //load the time to expiration in the output timer value. + if(aOpTime) + { + Time(aOpTime); + } + + //start setting the timer value... + clock_gettime(CLOCK_REALTIME, &iStartTime.it_value); + + iStartTime.it_interval = aIpTime->it_interval; + iEndTime = aIpTime->it_value; + + if((aFlag & TIMER_ABSTIME) == 0) // relative timer + { + iEndTime.tv_sec+=iStartTime.it_value.tv_sec; + iEndTime.tv_nsec+=iStartTime.it_value.tv_nsec; + } + getTimerHandler()->session.OnDemandConnect(getTimerHandler()->iServer); + TInt lRet = getTimerHandler()->session.SetTime(iTimerId); + return lRet; + } + +//gets the time to expiry. +TInt CRtTimer::Time(struct itimerspec *aTime) const + { + TInt err = KErrNone; + if(NULL == aTime) + { + err = KErrArgument; + } + else if (!iIsArmed) + { + memset(aTime, 0, sizeof(struct itimerspec)); + } + else + { + struct timespec clktime; + clock_gettime(CLOCK_REALTIME, &clktime); + + aTime->it_value.tv_sec = iEndTime.tv_sec - clktime.tv_sec; + aTime->it_value.tv_nsec = iEndTime.tv_nsec - clktime.tv_nsec; + aTime->it_interval = iStartTime.it_interval; + } + + return err; + } + +//gets the overruns for this timer +TInt CRtTimer::OverrunCount(TInt& aOverrunCount) const + { +#if (!defined SYMBIAN_OE_POSIX_SIGNALS || !defined SYMBIAN_OE_LIBRT) + aOverrunCount = aOverrunCount;//warning fix + return KErrNotSupported; + +#else + aOverrunCount = Backend()->Overrun(iTimerId); + if(aOverrunCount >= DELAYTIMER_MAX) + aOverrunCount = DELAYTIMER_MAX; + + return KErrNone; +#endif + } +//EOF +