|
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 : timer.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 #include <e32math.h> |
|
22 |
|
23 #include "sysif.h" |
|
24 #include "timer.h" |
|
25 #include "timerhandler.h" |
|
26 #include "timermessage.h" |
|
27 |
|
28 #define BOUNDARY_CHECK(rqtp) ((rqtp.tv_nsec != 0 && rqtp.tv_nsec < 1000) || \ |
|
29 rqtp.tv_nsec >= 1000000000L )\ |
|
30 |
|
31 //ctor |
|
32 static TInt64 seed = 0xdeadbeef; |
|
33 CRtTimer::CRtTimer(struct sigevent *aSig) |
|
34 { |
|
35 iTimer.Set(this); |
|
36 iTimerId = Math::Rand (seed); |
|
37 |
|
38 if(aSig == NULL) |
|
39 { |
|
40 iSigEvent.sigev_notify = SIGEV_SIGNAL; |
|
41 iSigEvent.sigev_signo = SIGALRM; |
|
42 } |
|
43 else |
|
44 { |
|
45 iSigEvent = *aSig; |
|
46 } |
|
47 |
|
48 iIsArmed = EFalse; |
|
49 } |
|
50 |
|
51 //dtor |
|
52 CRtTimer::~CRtTimer() |
|
53 { |
|
54 //should be called in context of the timer server thread. |
|
55 if(iIsArmed) |
|
56 { |
|
57 iTimer.Cancel(); |
|
58 } |
|
59 } |
|
60 |
|
61 //NewL method |
|
62 CRtTimer* CRtTimer::New(struct sigevent *aSig) |
|
63 { |
|
64 return new CRtTimer(aSig); |
|
65 } |
|
66 |
|
67 //sets the timer for the given value |
|
68 TInt CRtTimer::SetTime(TInt aFlag, const struct itimerspec *aIpTime, |
|
69 struct itimerspec *aOpTime) |
|
70 { |
|
71 //Check for boundary values of seconds and microseconds |
|
72 if (aIpTime == NULL || ((BOUNDARY_CHECK(aIpTime->it_value) || BOUNDARY_CHECK(aIpTime->it_interval)) && |
|
73 (aIpTime->it_value.tv_sec != 0 || aIpTime->it_value.tv_nsec != 0)) ) |
|
74 { |
|
75 return KErrArgument; |
|
76 } |
|
77 |
|
78 if(aIpTime->it_value.tv_sec == 0 && aIpTime->it_value.tv_nsec == 0) |
|
79 { |
|
80 if(!iIsArmed) |
|
81 return KErrNone; |
|
82 else |
|
83 iIsTimerReset = ETrue; |
|
84 } |
|
85 |
|
86 //load the time to expiration in the output timer value. |
|
87 if(aOpTime) |
|
88 { |
|
89 Time(aOpTime); |
|
90 } |
|
91 |
|
92 //start setting the timer value... |
|
93 clock_gettime(CLOCK_REALTIME, &iStartTime.it_value); |
|
94 |
|
95 iStartTime.it_interval = aIpTime->it_interval; |
|
96 iEndTime = aIpTime->it_value; |
|
97 |
|
98 if((aFlag & TIMER_ABSTIME) == 0) // relative timer |
|
99 { |
|
100 iEndTime.tv_sec+=iStartTime.it_value.tv_sec; |
|
101 iEndTime.tv_nsec+=iStartTime.it_value.tv_nsec; |
|
102 } |
|
103 getTimerHandler()->session.OnDemandConnect(getTimerHandler()->iServer); |
|
104 TInt lRet = getTimerHandler()->session.SetTime(iTimerId); |
|
105 return lRet; |
|
106 } |
|
107 |
|
108 //gets the time to expiry. |
|
109 TInt CRtTimer::Time(struct itimerspec *aTime) const |
|
110 { |
|
111 TInt err = KErrNone; |
|
112 if(NULL == aTime) |
|
113 { |
|
114 err = KErrArgument; |
|
115 } |
|
116 else if (!iIsArmed) |
|
117 { |
|
118 memset(aTime, 0, sizeof(struct itimerspec)); |
|
119 } |
|
120 else |
|
121 { |
|
122 struct timespec clktime; |
|
123 clock_gettime(CLOCK_REALTIME, &clktime); |
|
124 |
|
125 aTime->it_value.tv_sec = iEndTime.tv_sec - clktime.tv_sec; |
|
126 aTime->it_value.tv_nsec = iEndTime.tv_nsec - clktime.tv_nsec; |
|
127 aTime->it_interval = iStartTime.it_interval; |
|
128 } |
|
129 |
|
130 return err; |
|
131 } |
|
132 |
|
133 //gets the overruns for this timer |
|
134 TInt CRtTimer::OverrunCount(TInt& aOverrunCount) const |
|
135 { |
|
136 #if (!defined SYMBIAN_OE_POSIX_SIGNALS || !defined SYMBIAN_OE_LIBRT) |
|
137 aOverrunCount = aOverrunCount;//warning fix |
|
138 return KErrNotSupported; |
|
139 |
|
140 #else |
|
141 aOverrunCount = Backend()->Overrun(iTimerId); |
|
142 if(aOverrunCount >= DELAYTIMER_MAX) |
|
143 aOverrunCount = DELAYTIMER_MAX; |
|
144 |
|
145 return KErrNone; |
|
146 #endif |
|
147 } |
|
148 //EOF |
|
149 |