1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  *  Asynchronous interval timer.
19  */
20 
21 #include "IntervalTimer.h"
22 #include "OverrideLog.h"
23 
24 
IntervalTimer()25 IntervalTimer::IntervalTimer()
26 {
27     mTimerId = 0;
28     mCb = NULL;
29 }
30 
31 
set(int ms,TIMER_FUNC cb)32 bool IntervalTimer::set(int ms, TIMER_FUNC cb)
33 {
34     if (mTimerId == 0)
35     {
36         if (cb == NULL)
37             return false;
38 
39         if (!create(cb))
40             return false;
41     }
42     if (cb != mCb)
43     {
44         kill();
45         if (!create(cb))
46             return false;
47     }
48 
49     int stat = 0;
50     struct itimerspec ts;
51     ts.it_value.tv_sec = ms / 1000;
52     ts.it_value.tv_nsec = (ms % 1000) * 1000000;
53 
54     ts.it_interval.tv_sec = 0;
55     ts.it_interval.tv_nsec = 0;
56 
57     stat = timer_settime(mTimerId, 0, &ts, 0);
58     if (stat == -1)
59         ALOGE("IntervalTimer::set: fail set timer");
60     return stat == 0;
61 }
62 
63 
~IntervalTimer()64 IntervalTimer::~IntervalTimer()
65 {
66     kill();
67 }
68 
69 
kill()70 void IntervalTimer::kill()
71 {
72     if (mTimerId == 0)
73         return;
74 
75     timer_delete(mTimerId);
76     mTimerId = 0;
77     mCb = NULL;
78 }
79 
80 
create(TIMER_FUNC cb)81 bool IntervalTimer::create(TIMER_FUNC cb)
82 {
83     struct sigevent se;
84     int stat = 0;
85 
86     /*
87      * Set the sigevent structure to cause the signal to be
88      * delivered by creating a new thread.
89      */
90     se.sigev_notify = SIGEV_THREAD;
91     se.sigev_value.sival_ptr = &mTimerId;
92     se.sigev_notify_function = cb;
93     se.sigev_notify_attributes = NULL;
94     mCb = cb;
95     stat = timer_create(CLOCK_MONOTONIC, &se, &mTimerId);
96     if (stat == -1)
97         ALOGE("IntervalTimer::create: fail create timer");
98     return stat == 0;
99 }
100