Fix sftp loader
[petitboot] / ui / common / timer.c
1 /*
2  *  Copyright (C) 2009 Sony Computer Entertainment Inc.
3  *  Copyright 2009 Sony Corp.
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; version 2 of the License.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #if defined(HAVE_CONFIG_H)
20 #include "config.h"
21 #endif
22
23 #define _GNU_SOURCE
24 #include <assert.h>
25 #include <limits.h>
26 #include <unistd.h>
27
28 #include "log/log.h"
29 #include "timer.h"
30
31 /**
32  * ui_timer_init - Initialize the timer for use.
33  * @seconds: The final timeout value in seconds.
34  */
35
36 void ui_timer_init(struct ui_timer *timer, unsigned int seconds)
37 {
38         pb_log("%s: %u\n", __func__, seconds);
39         assert(!timer->disabled);
40         timer->timeout = seconds;
41 }
42
43 /**
44  * ui_timer_next - Calculate the next timer interval.
45  */
46
47 static unsigned int ui_timer_next(unsigned int seconds)
48 {
49         unsigned int next;
50
51         if (seconds == 0) {
52                 next = 0;
53                 goto done;
54         }
55
56         if (seconds <= 10) {
57                 next = 1;
58                 goto done;
59         }
60
61         if (seconds <= 60) {
62                 next = seconds % 5;
63                 next = next ? next : 5;
64                 goto done;
65         }
66
67         next = seconds % 10;
68         next = next ? next : 10;
69
70 done:
71         pb_log("%s: %u = %u\n", __func__, seconds, next);
72         return next;
73 }
74
75 /**
76  * ui_timer_kick - Kickstart the next timer interval.
77  */
78
79 void ui_timer_kick(struct ui_timer *timer)
80 {
81         unsigned int next;
82
83         if(timer->disabled)
84                 return;
85
86         if (timer->update_display)
87                 timer->update_display(timer, timer->timeout);
88
89         next = ui_timer_next(timer->timeout);
90         timer->timeout -= next;
91
92         if (next) {
93                 alarm(next);
94                 return;
95         }
96
97         pb_log("%s: timed out\n", __func__);
98
99         ui_timer_disable(timer);
100         timer->handle_timeout(timer);
101 }
102
103 /**
104  * ui_timer_disable - Stop and disable the timer.
105  */
106
107 void ui_timer_disable(struct ui_timer *timer)
108 {
109         if (timer->disabled)
110                 return;
111
112         pb_log("%s\n", __func__);
113         timer->disabled = 1;
114         timer->timeout = UINT_MAX;
115         alarm(0);
116 }
117
118 /**
119  * ui_timer_sigalrm
120  *
121  * Called at SIGALRM.
122  */
123
124 void ui_timer_sigalrm(struct ui_timer *timer)
125 {
126         timer->signaled = 1;
127 }
128
129 /**
130  * ui_timer_process_sig - Process a timer signal
131  */
132
133 void ui_timer_process_sig(struct ui_timer *timer)
134 {
135         while (timer->signaled) {
136                 timer->signaled = 0;
137                 ui_timer_kick(timer);
138         }
139 }