os/ossrv/genericopenlibs/posixrealtimeextensions/src/timerhandler.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/genericopenlibs/posixrealtimeextensions/src/timerhandler.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,246 @@
     1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// Name        : timerhandler.cpp
    1.18 +// Part of     : librt-timer specific cpp file
    1.19 +// This is a project specific source file for building the 
    1.20 +// timer related functions as part of librt library.
    1.21 +// 
    1.22 +//
    1.23 +
    1.24 +
    1.25 +#include "sysif.h"
    1.26 +#include "timerhandler.h"
    1.27 +#include "timerclient.h"
    1.28 +#include "timerserver.h"
    1.29 +#include "timermessage.h"
    1.30 +#include "timer.h"
    1.31 +#include <pthread.h>
    1.32 +
    1.33 +#ifdef __WINSCW__ 
    1.34 +#include <pls.h> // For emulator WSD API 
    1.35 +const TUid KLibrtUid3 = {0x2001E553}; 
    1.36 +#elif defined __X86GCC__
    1.37 +CTimerReqHandler gTimerHandler;
    1.38 +#endif
    1.39 +
    1.40 +
    1.41 +CTimerReqHandler* getTimerHandler()
    1.42 +	{
    1.43 +#ifdef __WINSCW__	
    1.44 +	// Access the PLS of this process
    1.45 +	CTimerReqHandler* lTimerHandlerPtr = Pls<CTimerReqHandler>(KLibrtUid3); 
    1.46 +	return lTimerHandlerPtr;  
    1.47 +#elif defined __X86GCC__
    1.48 +	return &gTimerHandler;
    1.49 +#else
    1.50 +	static CTimerReqHandler sgTimerHandler;
    1.51 +	return &sgTimerHandler;
    1.52 +#endif
    1.53 +	}
    1.54 +
    1.55 +
    1.56 + CTimerReqHandler::CTimerReqHandler() : iTimers(CTimerReqHandler::KTimersGran)
    1.57 +	{
    1.58 +	iTimersLock.CreateLocal();
    1.59 +	iServConnectLock.CreateLocal();
    1.60 +	iTimerSemaphore.CreateLocal(0);
    1.61 +	}
    1.62 +
    1.63 +
    1.64 + CTimerReqHandler::~CTimerReqHandler()
    1.65 +	{
    1.66 +	iTimersLock.Close();
    1.67 +	iTimers.ResetAndDestroy();
    1.68 +	iTimerSemaphore.Close();
    1.69 +	iServ.Close();
    1.70 +	iServConnectLock.Close();
    1.71 +	}
    1.72 +
    1.73 +//method to create a timer
    1.74 +TInt CTimerReqHandler::CreateTimer(TInt& aTimerId, struct sigevent *aSig)
    1.75 +	{
    1.76 +	TInt lRet = KErrNone;
    1.77 +	if(iTimers.Count() >= MAXTIMERLIMIT)
    1.78 +		{
    1.79 +		lRet = KErrWouldBlock;
    1.80 +		}
    1.81 +		
    1.82 +	if(lRet == KErrNone)
    1.83 +		{
    1.84 +		if(aSig != NULL)
    1.85 +			{
    1.86 +			switch(aSig->sigev_notify)	
    1.87 +				{
    1.88 +				case SIGEV_SIGNAL:
    1.89 +#if (!defined SYMBIAN_OE_POSIX_SIGNALS || !defined SYMBIAN_OE_LIBRT)
    1.90 +					{
    1.91 +					aTimerId = -1;
    1.92 +					lRet = KErrNotSupported;
    1.93 +					break;	
    1.94 +					}
    1.95 +#else			
    1.96 +				
    1.97 +				if(aSig->sigev_signo < 1 || aSig->sigev_signo > SIGRTMAX)
    1.98 +					{
    1.99 +					aTimerId = -1;
   1.100 +					lRet = KErrArgument;						
   1.101 +					}
   1.102 +#endif	
   1.103 +					
   1.104 +				case SIGEV_NONE:					
   1.105 +				case SIGEV_THREAD:
   1.106 +					break;
   1.107 +				default:
   1.108 +					aTimerId = -1;	
   1.109 +					lRet = KErrArgument;
   1.110 +					break;
   1.111 +				}
   1.112 +			}
   1.113 +			
   1.114 +		if(lRet == KErrNone)	
   1.115 +			{
   1.116 +			RHeap* oldHeap = User::SwitchHeap(Backend()->Heap());
   1.117 +			CRtTimer *lTimer = CRtTimer::New(aSig);
   1.118 +			if(NULL == lTimer)
   1.119 +				{
   1.120 +				aTimerId = -1;	
   1.121 +				lRet = KErrNoMemory;
   1.122 +				User::SwitchHeap(oldHeap);
   1.123 +				}
   1.124 +			else
   1.125 +				{
   1.126 +				aTimerId = lTimer->iTimerId;				
   1.127 +				iTimersLock.Wait();	
   1.128 +				TRAP(lRet, iTimers.AppendL(lTimer));				
   1.129 +				User::SwitchHeap(oldHeap);
   1.130 +				iTimersLock.Signal();			
   1.131 +				}	
   1.132 +			}
   1.133 +		}
   1.134 +		
   1.135 +	return lRet;	
   1.136 +	}
   1.137 +
   1.138 +//method to delete a timer
   1.139 +TInt CTimerReqHandler::RemoveTimer(const TInt& aTimerId)
   1.140 +	{
   1.141 +	if(FindTimer(aTimerId)== NULL)
   1.142 +		{
   1.143 +		return KErrArgument;
   1.144 +		}
   1.145 +	TInt lRet = Connect();
   1.146 +	if(lRet == KErrNone)
   1.147 +		{
   1.148 +		session.OnDemandConnect(iServer);
   1.149 +		lRet = session.DeleteTimer(aTimerId);
   1.150 +		}	
   1.151 +	return lRet;		
   1.152 +	}
   1.153 +
   1.154 +//method to set a new timeout value for a timer
   1.155 +TInt CTimerReqHandler::SetTime(const TInt& aTimerId, TInt aFlag, const struct itimerspec *aIpTime,
   1.156 +			 struct itimerspec *aOpTime) 
   1.157 +	{
   1.158 +	TInt lRet = Connect();
   1.159 +	if(lRet == KErrNone)
   1.160 +		{
   1.161 +		CRtTimer* lTimer = FindTimer(aTimerId);	
   1.162 +		if(lTimer != NULL)
   1.163 +			lRet = lTimer->SetTime(aFlag, aIpTime, aOpTime);	
   1.164 +		else
   1.165 +			lRet = KErrArgument;	
   1.166 +		}
   1.167 +		
   1.168 +	return lRet;	
   1.169 +	}
   1.170 +
   1.171 +//method to makesure that the timer server is started only once on demand.
   1.172 +TInt CTimerReqHandler::Connect()
   1.173 +	{
   1.174 +	TInt lRet = KErrNone;
   1.175 +	
   1.176 +	iServConnectLock.Wait();
   1.177 +	if(!iIsServStarted)
   1.178 +		{
   1.179 +		lRet = StartTimerServer();
   1.180 +		if(lRet == KErrNone)
   1.181 +			iIsServStarted = ETrue;
   1.182 +		}
   1.183 +	iServConnectLock.Signal();
   1.184 +	return lRet;		
   1.185 +	}
   1.186 +
   1.187 +//start up function for the timer server.
   1.188 +static TInt sTimerServer(TAny*)
   1.189 +	{
   1.190 +	RHeap *oldHeap = User::SwitchHeap(Backend()->Heap());
   1.191 +	CTrapCleanup* cleanup = CTrapCleanup::New();
   1.192 +	TRAPD(ret, CTimerServer::NewTimerServerL());
   1.193 +	delete cleanup;
   1.194 +	User::SwitchHeap(oldHeap);
   1.195 +	return ret;
   1.196 +	}
   1.197 +
   1.198 +//method to start the timer server
   1.199 +TInt CTimerReqHandler::StartTimerServer()
   1.200 +	{
   1.201 +	TRequestStatus status;
   1.202 +	TInt lRet = iServ.Create(KNullDesC, sTimerServer, 
   1.203 +			KDefaultStackSize, NULL, (TAny*)NULL);
   1.204 +	if(lRet == KErrNone)							
   1.205 +		{
   1.206 +		iServ.SetPriority(EPriorityAbsoluteHigh);// match the signal server priority.
   1.207 +		iServ.Rendezvous(status);
   1.208 +		iServ.Resume(); //get this ready
   1.209 +		User::WaitForRequest(status);
   1.210 +		}
   1.211 +	return lRet;
   1.212 +	}
   1.213 +
   1.214 +//method to get the "time to expiration" of a timer
   1.215 +TInt CTimerReqHandler::Time(const TInt& aTimerId, struct itimerspec *aTime)
   1.216 +	{
   1.217 + 	CRtTimer* lTimer = FindTimer(aTimerId);
   1.218 +	if(lTimer == NULL)
   1.219 +		return KErrArgument;	
   1.220 +	return lTimer->Time(aTime);
   1.221 +	}
   1.222 +
   1.223 +//method to get the overruns for a timer
   1.224 +TInt CTimerReqHandler::OverrunCount(const TInt& aTimerId, TInt& aOverrunCount)
   1.225 +	{
   1.226 +	CRtTimer* lTimer = FindTimer(aTimerId);
   1.227 +	if(lTimer == NULL)
   1.228 +		return KErrArgument;		
   1.229 +	return lTimer->OverrunCount(aOverrunCount);
   1.230 +	}
   1.231 +
   1.232 +//find the timer with the given timer id
   1.233 +CRtTimer* CTimerReqHandler::FindTimer(const TInt& aTimerId)
   1.234 +	{
   1.235 +	CRtTimer* lRtTimerP = NULL;
   1.236 +	iTimersLock.Wait();	
   1.237 +	TInt lTimerCount = iTimers.Count();	
   1.238 +	for(TInt lIdx =0; lIdx < lTimerCount; lIdx++)
   1.239 +		{
   1.240 +		if(iTimers[lIdx]->iTimerId == aTimerId)
   1.241 +			{
   1.242 +			lRtTimerP = (iTimers[lIdx]);
   1.243 +			break;	
   1.244 +			}
   1.245 +		}
   1.246 +	iTimersLock.Signal();
   1.247 +	return lRtTimerP;	
   1.248 +	}
   1.249 +