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