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 +