fixes init script for non ipv6 enabled systems #472755
[packages/xinetd.git] / xinetd / xtimer.c
1 /*
2  * (c) Copyright 1998-2001 by Rob Braun
3  * All rights reserved.  The file named COPYRIGHT specifies the terms 
4  * and conditions for redistribution.
5  */
6
7 #include <time.h>
8
9 #include "config.h"
10 #include "xtimer.h"
11 #include "pset.h"
12 #include "msg.h"
13
14 /* A note on the usage of timers in these functions:
15  * The timers are composed of 3 elements, a pointer to a callback function,
16  * the expire time of the timer, and a unique (pseudo-monotomically increasing)
17  * identifier for the timer.
18  * Timers are kept in a pset_h (linked list) and are sorted at insertion
19  * time, with the nearest expire time first.  The sort at insertion is to
20  * avoid examining non-expired timers in the xtimer_poll() function, and
21  * to be able to easily retrieve the next expiring timer.  
22  * The timers are set in the main event loop, using select() as the
23  * timing device.  select() sleeps until the next timer is set to expire
24  * (or until an FD is ready, in which case it also examines the timer list).
25  */
26
27 static pset_h xtimer_list = NULL;
28
29 static int xtimer_init( void )
30 {
31         if( xtimer_list != NULL )
32                 return 0;
33
34         xtimer_list = pset_create( 0, 0 );
35         if( xtimer_list == NULL ) 
36                 return -1;
37
38         return 0;
39 }
40
41 static int xtimer_compfunc( const void *_a, const void *_b )
42 {
43         xtime_h **a = (xtime_h **)_a;
44         xtime_h **b = (xtime_h **)_b;
45         return ((*a)->when - (*b)->when);
46 }
47
48 /* xtimer_add:
49  * Adds a timer to the pset_h of timers, and sorts the timer list (least time
50  * remaining first).
51  * Return values:
52  * Success: the timer ID which can be used to later remove the timer (>0)
53  * Failure: -1
54  */
55 int xtimer_add( void (*func)(void), time_t secs )
56 {
57         xtime_h *new_xtimer = NULL;
58         time_t tmptime;
59         unsigned count;
60
61         if( xtimer_list == NULL ) {
62                 if( xtimer_init() < 0 )
63                         return -1;
64         }
65
66         new_xtimer = (xtime_h *)malloc(sizeof(xtime_h));
67         if( new_xtimer == NULL ) {
68                 return -1;
69         }
70
71         tmptime = time(NULL);
72         if( tmptime == -1 ) {
73                 free( new_xtimer );
74                 return -1;
75         }
76         
77         new_xtimer->timerfunc = func;
78         new_xtimer->when =  tmptime + secs;
79
80         if( (count = pset_count( xtimer_list )) == 0 ) {
81            new_xtimer->xtid = 1;
82         } else {
83            new_xtimer->xtid = ((xtime_h *)(pset_pointer(xtimer_list, count-1)))->xtid + 1;
84         }
85
86         if( pset_add( xtimer_list, new_xtimer ) == NULL ) {
87                 free( new_xtimer );
88                 return -1;
89         }
90                 
91         pset_sort( xtimer_list, xtimer_compfunc );
92         
93         return(new_xtimer->xtid);
94 }
95
96 /* xtimer_poll:
97  * Traverses the pset_h of timers, and executes the callback for expired
98  * timers.  Timers that are expired, and have their callback executed
99  * are removed from the list of timers. 
100  */
101 int xtimer_poll(void)
102 {
103         unsigned int i;
104         
105         if( xtimer_list == NULL )
106                 return(0);
107
108         for( i = 0; i < pset_count( xtimer_list ); i++ ) {
109                 xtime_h *cur_timer = pset_pointer( xtimer_list, i );
110                 time_t cur_time    = time(NULL);
111
112                 /* The list is sorted, low to high.  If there's no
113                  * timers left, return.
114                  */
115                 if( cur_timer->when > cur_time ) {
116                         return(0);
117                 }
118                 cur_timer->timerfunc();
119                 pset_delete( xtimer_list, cur_timer );
120                 free(cur_timer);
121                 i--;
122                 cur_timer = NULL;
123         }
124
125         return(0);
126 }
127
128 /* xtimer_remove:
129  * Removes a timer from the list of timers.  Takes the timer id as an argument
130  * Returns:
131  * Success: 0
132  * Failure: -1
133  */
134 int xtimer_remove(int xtid)
135 {
136         unsigned int i;
137         int ret = -1;
138
139         for( i = 0; i < pset_count( xtimer_list ); i++ ) {
140                 xtime_h *cur_timer = pset_pointer( xtimer_list, i );
141                 if( cur_timer->xtid == xtid ) {
142                         pset_delete( xtimer_list, cur_timer );
143                         free( cur_timer );
144                         cur_timer = NULL;
145                         ret = 0;
146                 }
147         }
148
149         return(ret);
150 }
151
152 /* xtimer_nexttime:
153  * Returns the number of seconds until the next timer expires.
154  * Returns -1 when no timers are active.
155  */
156 time_t xtimer_nexttime(void)
157 {
158         time_t ret;
159
160         if(xtimer_list == NULL)
161                 return -1;
162
163         if( pset_count(xtimer_list) == 0 )
164                 return -1;
165
166         ret = ((xtime_h *)pset_pointer(xtimer_list, 0))->when - time(NULL) ;
167         if( ret < 0 )
168                 ret = 0;
169         return( ret );
170 }
171