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 #define LOG_TAG "IntervalTimer"
17 
18 /*
19  *  Asynchronous interval timer.
20  */
21 
22 #include "IntervalTimer.h"
23 #include "_OverrideLog.h"
24 
25 
IntervalTimer()26 IntervalTimer::IntervalTimer()
27 {
28     mTimerId = 0;
29     mCb = NULL;
30 }
31 
32 
set(int ms,TIMER_FUNC cb)33 bool IntervalTimer::set(int ms, TIMER_FUNC cb)
34 {
35     if (mTimerId == 0)
36     {
37         if (cb == NULL)
38             return false;
39 
40         if (!create(cb))
41             return false;
42     }
43     if (cb != mCb)
44     {
45         kill();
46         if (!create(cb))
47             return false;
48     }
49 
50     int stat = 0;
51     struct itimerspec ts;
52     ts.it_value.tv_sec = ms / 1000;
53     ts.it_value.tv_nsec = (ms % 1000) * 1000000;
54 
55     ts.it_interval.tv_sec = 0;
56     ts.it_interval.tv_nsec = 0;
57 
58     stat = timer_settime(mTimerId, 0, &ts, 0);
59     if (stat == -1)
60         ALOGE("fail set timer");
61     return stat == 0;
62 }
63 
64 
~IntervalTimer()65 IntervalTimer::~IntervalTimer()
66 {
67     kill();
68 }
69 
70 
kill()71 void IntervalTimer::kill()
72 {
73     if (mTimerId == 0)
74         return;
75 
76     timer_delete(mTimerId);
77     mTimerId = 0;
78     mCb = NULL;
79 }
80 
81 
create(TIMER_FUNC cb)82 bool IntervalTimer::create(TIMER_FUNC cb)
83 {
84     struct sigevent se;
85     int stat = 0;
86 
87     /*
88      * Set the sigevent structure to cause the signal to be
89      * delivered by creating a new thread.
90      */
91     se.sigev_notify = SIGEV_THREAD;
92     se.sigev_value.sival_ptr = &mTimerId;
93     se.sigev_notify_function = cb;
94     se.sigev_notify_attributes = NULL;
95     mCb = cb;
96     stat = timer_create(CLOCK_MONOTONIC, &se, &mTimerId);
97     if (stat == -1)
98         ALOGE("fail create timer");
99     return stat == 0;
100 }
101