diff -up cups-1.5.0/scheduler/cupsd.h.avahi-3-timeouts cups-1.5.0/scheduler/cupsd.h --- cups-1.5.0/scheduler/cupsd.h.avahi-3-timeouts 2011-05-11 23:17:34.000000000 +0100 +++ cups-1.5.0/scheduler/cupsd.h 2011-10-07 13:20:41.522867324 +0100 @@ -140,6 +140,15 @@ extern const char *cups_hstrerror(int); typedef void (*cupsd_selfunc_t)(void *data); +#ifdef HAVE_AVAHI +/* + * Timeout callback function type... + */ + +typedef struct _cupsd_timeout_s cupsd_timeout_t; +typedef void (*cupsd_timeoutfunc_t)(cupsd_timeout_t *timeout, void *data); +#endif /* HAVE_AVAHI */ + /* * Globals... @@ -173,6 +182,11 @@ VAR int Launchd VALUE(0); /* Running from launchd */ #endif /* HAVE_LAUNCH_H */ +#ifdef HAVE_AVAHI +VAR cups_array_t *Timeouts; /* Timed callbacks for main loop */ +#endif /* HAVE_AVAHI */ + + /* * Prototypes... @@ -242,6 +256,20 @@ extern void cupsdStopSelect(void); extern void cupsdStartServer(void); extern void cupsdStopServer(void); +#ifdef HAVE_AVAHI +extern void cupsdInitTimeouts(void); +extern cupsd_timeout_t *cupsdAddTimeout (const struct timeval *tv, + cupsd_timeoutfunc_t cb, + void *data); +extern cupsd_timeout_t *cupsdNextTimeout (long *delay); +extern void cupsdRunTimeout (cupsd_timeout_t *timeout); +extern void cupsdUpdateTimeout (cupsd_timeout_t *timeout, + const struct timeval *tv); +extern void cupsdRemoveTimeout (cupsd_timeout_t *timeout); +#endif /* HAVE_AVAHI */ + +extern int cupsdRemoveFile(const char *filename); + /* * End of "$Id: cupsd.h 9766 2011-05-11 22:17:34Z mike $". diff -up cups-1.5.0/scheduler/main.c.avahi-3-timeouts cups-1.5.0/scheduler/main.c --- cups-1.5.0/scheduler/main.c.avahi-3-timeouts 2011-10-07 13:20:36.875954675 +0100 +++ cups-1.5.0/scheduler/main.c 2011-10-07 13:20:41.524867282 +0100 @@ -146,6 +146,10 @@ main(int argc, /* I - Number of comm int launchd_idle_exit; /* Idle exit on select timeout? */ #endif /* HAVE_LAUNCHD */ +#ifdef HAVE_AVAHI + cupsd_timeout_t *tmo; /* Next scheduled timed callback */ + long tmo_delay; /* Time before it must be called */ +#endif /* HAVE_AVAHI */ #ifdef HAVE_GETEUID @@ -535,6 +539,14 @@ main(int argc, /* I - Number of comm httpInitialize(); +#ifdef HAVE_AVAHI + /* + * Initialize timed callback structures. + */ + + cupsdInitTimeouts(); +#endif /* HAVE_AVAHI */ + cupsdStartServer(); /* @@ -874,6 +886,16 @@ main(int argc, /* I - Number of comm } #endif /* __APPLE__ */ +#ifdef HAVE_AVAHI + /* + * If a timed callback is due, run it. + */ + + tmo = cupsdNextTimeout (&tmo_delay); + if (tmo && tmo_delay == 0) + cupsdRunTimeout (tmo); +#endif /* HAVE_AVAHI */ + #ifndef __APPLE__ /* * Update the network interfaces once a minute... @@ -1787,6 +1809,10 @@ select_timeout(int fds) /* I - Number cupsd_job_t *job; /* Job information */ cupsd_subscription_t *sub; /* Subscription information */ const char *why; /* Debugging aid */ +#ifdef HAVE_AVAHI + cupsd_timeout_t *tmo; /* Timed callback */ + long tmo_delay; /* Seconds before calling it */ +#endif /* HAVE_AVAHI */ /* @@ -1829,6 +1855,19 @@ select_timeout(int fds) /* I - Number } #endif /* __APPLE__ */ +#ifdef HAVE_AVAHI + /* + * See if there are any scheduled timed callbacks to run. + */ + + tmo = cupsdNextTimeout (&tmo_delay); + if (tmo) + { + timeout = tmo_delay; + why = "run a timed callback"; + } +#endif /* HAVE_AVAHI */ + /* * Check whether we are accepting new connections... */ diff -up cups-1.5.0/scheduler/Makefile.avahi-3-timeouts cups-1.5.0/scheduler/Makefile --- cups-1.5.0/scheduler/Makefile.avahi-3-timeouts 2011-10-07 13:20:36.955953170 +0100 +++ cups-1.5.0/scheduler/Makefile 2011-10-07 13:20:41.521867343 +0100 @@ -39,7 +39,8 @@ CUPSDOBJS = \ server.o \ statbuf.o \ subscriptions.o \ - sysman.o + sysman.o \ + timeout.o LIBOBJS = \ filter.o \ mime.o \ diff -up cups-1.5.0/scheduler/timeout.c.avahi-3-timeouts cups-1.5.0/scheduler/timeout.c --- cups-1.5.0/scheduler/timeout.c.avahi-3-timeouts 2011-10-07 13:20:41.525867259 +0100 +++ cups-1.5.0/scheduler/timeout.c 2011-10-07 13:20:41.525867259 +0100 @@ -0,0 +1,235 @@ +/* + * "$Id$" + * + * Timeout functions for the Common UNIX Printing System (CUPS). + * + * Copyright (C) 2010, 2011 Red Hat, Inc. + * Authors: + * Tim Waugh + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Contents: + * + * cupsdInitTimeouts() - Initialise timeout structure. + * cupsdAddTimeout() - Add a timed callback. + * cupsdNextTimeout() - Find the next enabled timed callback. + * cupsdUpdateTimeout() - Adjust the time of a timed callback or disable it. + * cupsdRemoveTimeout() - Discard a timed callback. + * compare_timeouts() - Compare timed callbacks for array sorting. + */ + +#include + +#ifdef HAVE_AVAHI /* Applies to entire file... */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" + +#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO) +# include +#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */ + +#ifdef HAVE_AVAHI +# include +#endif /* HAVE_AVAHI */ + + +struct _cupsd_timeout_s +{ + struct timeval when; + int enabled; + cupsd_timeoutfunc_t callback; + void *data; +}; + +/* + * Local functions... + */ + +/* + * 'compare_timeouts()' - Compare timed callbacks for array sorting. + */ + +static int +compare_addrs (void *p0, void *p1) +{ + if (p0 == p1) + return (0); + if (p0 < p1) + return (-1); + return (1); +} + +static int +compare_timeouts (cupsd_timeout_t *p0, cupsd_timeout_t *p1) +{ + int addrsdiff = compare_addrs (p0, p1); + int tvdiff; + + if (addrsdiff == 0) + return (0); + + if (!p0->enabled || !p1->enabled) + { + if (!p0->enabled && !p1->enabled) + return (addrsdiff); + + return (p0->enabled ? -1 : 1); + } + + tvdiff = avahi_timeval_compare (&p0->when, &p1->when); + if (tvdiff != 0) + return (tvdiff); + + return (addrsdiff); +} + + +/* + * 'cupsdInitTimeouts()' - Initialise timeout structures. + */ + +void +cupsdInitTimeouts(void) +{ + Timeouts = cupsArrayNew ((cups_array_func_t)compare_timeouts, NULL); +} + + +/* + * 'cupsdAddTimeout()' - Add a timed callback. + */ + +cupsd_timeout_t * /* O - Timeout handle */ +cupsdAddTimeout(const struct timeval *tv, /* I - Absolute time */ + cupsd_timeoutfunc_t cb, /* I - Callback function */ + void *data) /* I - User data */ +{ + cupsd_timeout_t *timeout; + + timeout = malloc (sizeof(cupsd_timeout_t)); + if (timeout != NULL) + { + timeout->enabled = (tv != NULL); + if (tv) + { + timeout->when.tv_sec = tv->tv_sec; + timeout->when.tv_usec = tv->tv_usec; + } + + timeout->callback = cb; + timeout->data = data; + cupsArrayAdd (Timeouts, timeout); + } + + return timeout; +} + + +/* + * 'cupsdNextTimeout()' - Find the next enabled timed callback. + */ + +cupsd_timeout_t * /* O - Next enabled timeout or NULL */ +cupsdNextTimeout(long *delay) /* O - Seconds before scheduled */ +{ + cupsd_timeout_t *first = cupsArrayFirst (Timeouts); + struct timeval curtime; + + if (first && !first->enabled) + first = NULL; + + if (first && delay) + { + gettimeofday (&curtime, NULL); + if (avahi_timeval_compare (&curtime, &first->when) > 0) + { + *delay = 0; + } else { + *delay = 1 + first->when.tv_sec - curtime.tv_sec; + if (first->when.tv_usec < curtime.tv_usec) + (*delay)--; + } + } + + return (first); +} + + +/* + * 'cupsdRunTimeout()' - Run a timed callback. + */ + +void +cupsdRunTimeout(cupsd_timeout_t *timeout) /* I - Timeout */ +{ + if (!timeout) + return; + timeout->enabled = 0; + if (!timeout->callback) + return; + timeout->callback (timeout, timeout->data); +} + +/* + * 'cupsdUpdateTimeout()' - Adjust the time of a timed callback or disable it. + */ + +void +cupsdUpdateTimeout(cupsd_timeout_t *timeout, /* I - Timeout */ + const struct timeval *tv) /* I - Absolute time or NULL */ +{ + cupsArrayRemove (Timeouts, timeout); + timeout->enabled = (tv != NULL); + if (tv) + { + timeout->when.tv_sec = tv->tv_sec; + timeout->when.tv_usec = tv->tv_usec; + } + cupsArrayAdd (Timeouts, timeout); +} + + +/* + * 'cupsdRemoveTimeout()' - Discard a timed callback. + */ + +void +cupsdRemoveTimeout(cupsd_timeout_t *timeout) /* I - Timeout */ +{ + cupsArrayRemove (Timeouts, timeout); + free (timeout); +} + + +#endif /* HAVE_AVAHI ... from top of file */ + +/* + * End of "$Id$". + */