genericopenlibs/posixrealtimeextensions/src/timer.cpp
changeset 0 e4d67989cc36
--- /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 <e32math.h> 
+
+#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
+