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