os/ossrv/genericopenlibs/posixrealtimeextensions/src/timerhandler.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Name        : timerhandler.cpp
    15 // Part of     : librt-timer specific cpp file
    16 // This is a project specific source file for building the 
    17 // timer related functions as part of librt library.
    18 // 
    19 //
    20 
    21 
    22 #include "sysif.h"
    23 #include "timerhandler.h"
    24 #include "timerclient.h"
    25 #include "timerserver.h"
    26 #include "timermessage.h"
    27 #include "timer.h"
    28 #include <pthread.h>
    29 
    30 #ifdef __WINSCW__ 
    31 #include <pls.h> // For emulator WSD API 
    32 const TUid KLibrtUid3 = {0x2001E553}; 
    33 #elif defined __X86GCC__
    34 CTimerReqHandler gTimerHandler;
    35 #endif
    36 
    37 
    38 CTimerReqHandler* getTimerHandler()
    39 	{
    40 #ifdef __WINSCW__	
    41 	// Access the PLS of this process
    42 	CTimerReqHandler* lTimerHandlerPtr = Pls<CTimerReqHandler>(KLibrtUid3); 
    43 	return lTimerHandlerPtr;  
    44 #elif defined __X86GCC__
    45 	return &gTimerHandler;
    46 #else
    47 	static CTimerReqHandler sgTimerHandler;
    48 	return &sgTimerHandler;
    49 #endif
    50 	}
    51 
    52 
    53  CTimerReqHandler::CTimerReqHandler() : iTimers(CTimerReqHandler::KTimersGran)
    54 	{
    55 	iTimersLock.CreateLocal();
    56 	iServConnectLock.CreateLocal();
    57 	iTimerSemaphore.CreateLocal(0);
    58 	}
    59 
    60 
    61  CTimerReqHandler::~CTimerReqHandler()
    62 	{
    63 	iTimersLock.Close();
    64 	iTimers.ResetAndDestroy();
    65 	iTimerSemaphore.Close();
    66 	iServ.Close();
    67 	iServConnectLock.Close();
    68 	}
    69 
    70 //method to create a timer
    71 TInt CTimerReqHandler::CreateTimer(TInt& aTimerId, struct sigevent *aSig)
    72 	{
    73 	TInt lRet = KErrNone;
    74 	if(iTimers.Count() >= MAXTIMERLIMIT)
    75 		{
    76 		lRet = KErrWouldBlock;
    77 		}
    78 		
    79 	if(lRet == KErrNone)
    80 		{
    81 		if(aSig != NULL)
    82 			{
    83 			switch(aSig->sigev_notify)	
    84 				{
    85 				case SIGEV_SIGNAL:
    86 #if (!defined SYMBIAN_OE_POSIX_SIGNALS || !defined SYMBIAN_OE_LIBRT)
    87 					{
    88 					aTimerId = -1;
    89 					lRet = KErrNotSupported;
    90 					break;	
    91 					}
    92 #else			
    93 				
    94 				if(aSig->sigev_signo < 1 || aSig->sigev_signo > SIGRTMAX)
    95 					{
    96 					aTimerId = -1;
    97 					lRet = KErrArgument;						
    98 					}
    99 #endif	
   100 					
   101 				case SIGEV_NONE:					
   102 				case SIGEV_THREAD:
   103 					break;
   104 				default:
   105 					aTimerId = -1;	
   106 					lRet = KErrArgument;
   107 					break;
   108 				}
   109 			}
   110 			
   111 		if(lRet == KErrNone)	
   112 			{
   113 			RHeap* oldHeap = User::SwitchHeap(Backend()->Heap());
   114 			CRtTimer *lTimer = CRtTimer::New(aSig);
   115 			if(NULL == lTimer)
   116 				{
   117 				aTimerId = -1;	
   118 				lRet = KErrNoMemory;
   119 				User::SwitchHeap(oldHeap);
   120 				}
   121 			else
   122 				{
   123 				aTimerId = lTimer->iTimerId;				
   124 				iTimersLock.Wait();	
   125 				TRAP(lRet, iTimers.AppendL(lTimer));				
   126 				User::SwitchHeap(oldHeap);
   127 				iTimersLock.Signal();			
   128 				}	
   129 			}
   130 		}
   131 		
   132 	return lRet;	
   133 	}
   134 
   135 //method to delete a timer
   136 TInt CTimerReqHandler::RemoveTimer(const TInt& aTimerId)
   137 	{
   138 	if(FindTimer(aTimerId)== NULL)
   139 		{
   140 		return KErrArgument;
   141 		}
   142 	TInt lRet = Connect();
   143 	if(lRet == KErrNone)
   144 		{
   145 		session.OnDemandConnect(iServer);
   146 		lRet = session.DeleteTimer(aTimerId);
   147 		}	
   148 	return lRet;		
   149 	}
   150 
   151 //method to set a new timeout value for a timer
   152 TInt CTimerReqHandler::SetTime(const TInt& aTimerId, TInt aFlag, const struct itimerspec *aIpTime,
   153 			 struct itimerspec *aOpTime) 
   154 	{
   155 	TInt lRet = Connect();
   156 	if(lRet == KErrNone)
   157 		{
   158 		CRtTimer* lTimer = FindTimer(aTimerId);	
   159 		if(lTimer != NULL)
   160 			lRet = lTimer->SetTime(aFlag, aIpTime, aOpTime);	
   161 		else
   162 			lRet = KErrArgument;	
   163 		}
   164 		
   165 	return lRet;	
   166 	}
   167 
   168 //method to makesure that the timer server is started only once on demand.
   169 TInt CTimerReqHandler::Connect()
   170 	{
   171 	TInt lRet = KErrNone;
   172 	
   173 	iServConnectLock.Wait();
   174 	if(!iIsServStarted)
   175 		{
   176 		lRet = StartTimerServer();
   177 		if(lRet == KErrNone)
   178 			iIsServStarted = ETrue;
   179 		}
   180 	iServConnectLock.Signal();
   181 	return lRet;		
   182 	}
   183 
   184 //start up function for the timer server.
   185 static TInt sTimerServer(TAny*)
   186 	{
   187 	RHeap *oldHeap = User::SwitchHeap(Backend()->Heap());
   188 	CTrapCleanup* cleanup = CTrapCleanup::New();
   189 	TRAPD(ret, CTimerServer::NewTimerServerL());
   190 	delete cleanup;
   191 	User::SwitchHeap(oldHeap);
   192 	return ret;
   193 	}
   194 
   195 //method to start the timer server
   196 TInt CTimerReqHandler::StartTimerServer()
   197 	{
   198 	TRequestStatus status;
   199 	TInt lRet = iServ.Create(KNullDesC, sTimerServer, 
   200 			KDefaultStackSize, NULL, (TAny*)NULL);
   201 	if(lRet == KErrNone)							
   202 		{
   203 		iServ.SetPriority(EPriorityAbsoluteHigh);// match the signal server priority.
   204 		iServ.Rendezvous(status);
   205 		iServ.Resume(); //get this ready
   206 		User::WaitForRequest(status);
   207 		}
   208 	return lRet;
   209 	}
   210 
   211 //method to get the "time to expiration" of a timer
   212 TInt CTimerReqHandler::Time(const TInt& aTimerId, struct itimerspec *aTime)
   213 	{
   214  	CRtTimer* lTimer = FindTimer(aTimerId);
   215 	if(lTimer == NULL)
   216 		return KErrArgument;	
   217 	return lTimer->Time(aTime);
   218 	}
   219 
   220 //method to get the overruns for a timer
   221 TInt CTimerReqHandler::OverrunCount(const TInt& aTimerId, TInt& aOverrunCount)
   222 	{
   223 	CRtTimer* lTimer = FindTimer(aTimerId);
   224 	if(lTimer == NULL)
   225 		return KErrArgument;		
   226 	return lTimer->OverrunCount(aOverrunCount);
   227 	}
   228 
   229 //find the timer with the given timer id
   230 CRtTimer* CTimerReqHandler::FindTimer(const TInt& aTimerId)
   231 	{
   232 	CRtTimer* lRtTimerP = NULL;
   233 	iTimersLock.Wait();	
   234 	TInt lTimerCount = iTimers.Count();	
   235 	for(TInt lIdx =0; lIdx < lTimerCount; lIdx++)
   236 		{
   237 		if(iTimers[lIdx]->iTimerId == aTimerId)
   238 			{
   239 			lRtTimerP = (iTimers[lIdx]);
   240 			break;	
   241 			}
   242 		}
   243 	iTimersLock.Signal();
   244 	return lRtTimerP;	
   245 	}
   246