Revert manifest to default one
[external/cups.git] / scheduler / timeout.c
1 /*
2  * "$Id$"
3  *
4  *   Timeout functions for the Common UNIX Printing System (CUPS).
5  *
6  *   Copyright (C) 2010 Red Hat, Inc.
7  *   Authors:
8  *     Tim Waugh <twaugh@redhat.com>
9  *
10  *   Distribution and use rights are outlined in the file "LICENSE.txt"
11  *   which should have been included with this file.  If this file is
12  *   file is missing or damaged, see the license at "http://www.cups.org/".
13  *
14  * Contents:
15  *
16  *   cupsdInitTimeouts()  - Initialise timeout structure.
17  *   cupsdAddTimeout()    - Add a timed callback.
18  *   cupsdNextTimeout()   - Find the next enabled timed callback.
19  *   cupsdUpdateTimeout() - Adjust the time of a timed callback or disable it.
20  *   cupsdRemoveTimeout() - Discard a timed callback.
21  *   compare_timeouts()   - Compare timed callbacks for array sorting.
22  */
23
24 #include <config.h>
25
26 #ifdef HAVE_AVAHI /* Applies to entire file... */
27
28 /*
29  * Include necessary headers...
30  */
31
32 #include "cupsd.h"
33
34 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
35 #  include <malloc.h>
36 #endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
37
38 #ifdef HAVE_AVAHI
39 #  include <avahi-common/timeval.h>
40 #endif /* HAVE_AVAHI */
41
42
43 struct _cupsd_timeout_s
44 {
45   struct timeval when;
46   int enabled;
47   cupsd_timeoutfunc_t callback;
48   void *data;
49 };
50
51 /*
52  * Local functions...
53  */
54
55 /*
56  * 'compare_timeouts()' - Compare timed callbacks for array sorting.
57  */
58
59 static int
60 compare_addrs (void *p0, void *p1)
61 {
62   if (p0 == p1)
63     return (0);
64   if (p0 < p1)
65     return (-1);
66   return (1);
67 }
68
69 static int
70 compare_timeouts (cupsd_timeout_t *p0, cupsd_timeout_t *p1)
71 {
72   int addrsdiff = compare_addrs (p0, p1);
73   int tvdiff;
74
75   if (addrsdiff == 0)
76     return (0);
77
78   if (!p0->enabled || !p1->enabled)
79   {
80     if (!p0->enabled && !p1->enabled)
81       return (addrsdiff);
82
83     return (p0->enabled ? -1 : 1);
84   }
85
86   tvdiff = avahi_timeval_compare (&p0->when, &p1->when);
87   if (tvdiff != 0)
88     return (tvdiff);
89
90   return (addrsdiff);
91 }
92
93
94 /*
95  * 'cupsdInitTimeouts()' - Initialise timeout structures.
96  */
97
98 void
99 cupsdInitTimeouts(void)
100 {
101   Timeouts = cupsArrayNew ((cups_array_func_t)compare_timeouts, NULL);
102 }
103
104
105 /*
106  * 'cupsdAddTimeout()' - Add a timed callback.
107  */
108
109 cupsd_timeout_t *                               /* O - Timeout handle */
110 cupsdAddTimeout(const struct timeval *tv,       /* I - Absolute time */
111                 cupsd_timeoutfunc_t cb,         /* I - Callback function */
112                 void *data)                     /* I - User data */
113 {
114   cupsd_timeout_t *timeout;
115
116   timeout = malloc (sizeof(cupsd_timeout_t));
117   if (timeout != NULL)
118   {
119     timeout->enabled = (tv != NULL);
120     if (tv)
121     {
122       timeout->when.tv_sec = tv->tv_sec;
123       timeout->when.tv_usec = tv->tv_usec;
124     }
125
126     timeout->callback = cb;
127     timeout->data = data;
128     cupsArrayAdd (Timeouts, timeout);
129   }
130
131   return timeout;
132 }
133
134
135 /*
136  * 'cupsdNextTimeout()' - Find the next enabled timed callback.
137  */
138
139 cupsd_timeout_t *               /* O - Next enabled timeout or NULL */
140 cupsdNextTimeout(long *delay)   /* O - Seconds before scheduled */
141 {
142   cupsd_timeout_t *first = cupsArrayFirst (Timeouts);
143   struct timeval curtime;
144
145   if (first && !first->enabled)
146     first = NULL;
147
148   if (first && delay)
149   {
150     gettimeofday (&curtime, NULL);
151     if (avahi_timeval_compare (&curtime, &first->when) > 0)
152     {
153       *delay = 0;
154     } else {
155       *delay = 1 + first->when.tv_sec - curtime.tv_sec;
156       if (first->when.tv_usec < curtime.tv_usec)
157         (*delay)--;
158     }
159   }
160
161   return (first);
162 }
163
164
165 /*
166  * 'cupsdRunTimeout()' - Run a timed callback.
167  */
168
169 void
170 cupsdRunTimeout(cupsd_timeout_t *timeout)       /* I - Timeout */
171 {
172   if (!timeout)
173     return;
174   timeout->enabled = 0;
175   if (!timeout->callback)
176     return;
177   timeout->callback (timeout, timeout->data);
178 }
179
180 /*
181  * 'cupsdUpdateTimeout()' - Adjust the time of a timed callback or disable it.
182  */
183
184 void
185 cupsdUpdateTimeout(cupsd_timeout_t *timeout,    /* I - Timeout */
186                    const struct timeval *tv)    /* I - Absolute time or NULL */
187 {
188   cupsArrayRemove (Timeouts, timeout);
189   timeout->enabled = (tv != NULL);
190   if (tv)
191   {
192     timeout->when.tv_sec = tv->tv_sec;
193     timeout->when.tv_usec = tv->tv_usec;
194   }
195   cupsArrayAdd (Timeouts, timeout);
196 }
197
198
199 /*
200  * 'cupsdRemoveTimeout()' - Discard a timed callback.
201  */
202
203 void
204 cupsdRemoveTimeout(cupsd_timeout_t *timeout)    /* I - Timeout */
205 {
206   cupsArrayRemove (Timeouts, timeout);
207   free (timeout);
208 }
209
210
211 #endif /* HAVE_AVAHI ... from top of file */
212
213 /*
214  * End of "$Id$".
215  */