From 2250539aeee0569f8861841d1f5ff16f1539715e Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sat, 5 Apr 2003 19:03:40 +0000 Subject: 2003-04-05 Havoc Pennington * bus/loop.c (bus_loop_iterate): fix the timeout code, using magic from GLib * dbus/dbus-spawn.c (_dbus_babysitter_unref): set sitter_pid to -1 once we've reaped the babysitter (_dbus_babysitter_handle_watch): do as much work as we can, not just one go of it * bus/activation.c: add code using DBusBabysitter so that we handle it when a service fails to start up properly. (bus_activation_service_created): don't remove the activation entries as we go, just let them get removed when we free the pending activation. Unref reply messages after sending them. --- bus/loop.c | 155 +++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 55 deletions(-) (limited to 'bus/loop.c') diff --git a/bus/loop.c b/bus/loop.c index a237defa..e2e129eb 100644 --- a/bus/loop.c +++ b/bus/loop.c @@ -312,6 +312,90 @@ bus_loop_remove_timeout (BusLoop *loop, timeout, function, data); } +/* Convolutions from GLib, there really must be a better way + * to do this. + */ +static dbus_bool_t +check_timeout (unsigned long tv_sec, + unsigned long tv_usec, + TimeoutCallback *tcb, + int *timeout) +{ + long sec; + long msec; + unsigned long expiration_tv_sec; + unsigned long expiration_tv_usec; + long interval_seconds; + long interval_milliseconds; + int interval; + + interval = dbus_timeout_get_interval (tcb->timeout); + + interval_seconds = interval / 1000; + interval_milliseconds = interval - interval_seconds * 1000; + + expiration_tv_sec = tcb->last_tv_sec + interval_seconds; + expiration_tv_usec = tcb->last_tv_usec + interval_milliseconds * 1000; + if (expiration_tv_usec >= 1000000) + { + expiration_tv_usec -= 1000000; + expiration_tv_sec += 1; + } + + sec = expiration_tv_sec - tv_sec; + msec = (expiration_tv_usec - tv_usec) / 1000; + +#if 0 + printf ("Interval is %ld seconds %ld msecs\n", + interval_seconds, + interval_milliseconds); + printf ("Now is %lu seconds %lu usecs\n", + tv_sec, tv_usec); + printf ("Exp is %lu seconds %lu usecs\n", + expiration_tv_sec, expiration_tv_usec); + printf ("Pre-correction, remaining sec %ld msec %ld\n", sec, msec); +#endif + + /* We do the following in a rather convoluted fashion to deal with + * the fact that we don't have an integral type big enough to hold + * the difference of two timevals in millseconds. + */ + if (sec < 0 || (sec == 0 && msec < 0)) + msec = 0; + else + { + if (msec < 0) + { + msec += 1000; + sec -= 1; + } + + if (sec > interval_seconds || + (sec == interval_seconds && msec > interval_milliseconds)) + { + /* The system time has been set backwards, reset the timeout */ + tcb->last_tv_sec = tv_sec; + tcb->last_tv_usec = tv_usec; + + msec = MIN (_DBUS_INT_MAX, interval); + + _dbus_verbose ("System clock went backward\n"); + } + else + { + msec = MIN (_DBUS_INT_MAX, (unsigned int)msec + 1000 * (unsigned int)sec); + } + } + + *timeout = msec; + +#if 0 + printf ("Timeout expires in %d milliseconds\n", *timeout); +#endif + + return msec == 0; +} + /* Returns TRUE if we have any timeouts or ready file descriptors, * which is just used in test code as a debug hack */ @@ -447,34 +531,15 @@ bus_loop_iterate (BusLoop *loop, dbus_timeout_get_enabled (TIMEOUT_CALLBACK (cb)->timeout)) { TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); - unsigned long interval; - unsigned long elapsed; + int msecs_remaining; - if (tcb->last_tv_sec > tv_sec || - (tcb->last_tv_sec == tv_sec && - tcb->last_tv_usec > tv_usec)) - { - /* Clock went backward, pretend timeout - * was just installed. - */ - tcb->last_tv_sec = tv_sec; - tcb->last_tv_usec = tv_usec; - _dbus_verbose ("System clock went backward\n"); - } - - interval = dbus_timeout_get_interval (tcb->timeout); + check_timeout (tv_sec, tv_usec, tcb, &msecs_remaining); - elapsed = - (tv_sec - tcb->last_tv_sec) * 1000 + - (tv_usec - tcb->last_tv_usec) / 1000; - - if (interval < elapsed) - timeout = 0; - else if (timeout < 0) - timeout = interval - elapsed; + if (timeout < 0) + timeout = msecs_remaining; else - timeout = MIN (((unsigned long)timeout), interval - elapsed); - + timeout = MIN (msecs_remaining, timeout); + _dbus_assert (timeout >= 0); if (timeout == 0) @@ -486,7 +551,12 @@ bus_loop_iterate (BusLoop *loop, } if (!block) - timeout = 0; + { + timeout = 0; +#if 0 + printf ("timeout is 0 as we aren't blocking\n"); +#endif + } /* if a watch is OOM, don't wait longer than the OOM * wait to re-enable it @@ -522,41 +592,17 @@ bus_loop_iterate (BusLoop *loop, dbus_timeout_get_enabled (TIMEOUT_CALLBACK (cb)->timeout)) { TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); - unsigned long interval; - unsigned long elapsed; - - if (tcb->last_tv_sec > tv_sec || - (tcb->last_tv_sec == tv_sec && - tcb->last_tv_usec > tv_usec)) - { - /* Clock went backward, pretend timeout - * was just installed. - */ - tcb->last_tv_sec = tv_sec; - tcb->last_tv_usec = tv_usec; - _dbus_verbose ("System clock went backward\n"); - goto next_timeout; - } - - interval = dbus_timeout_get_interval (tcb->timeout); - - elapsed = - (tv_sec - tcb->last_tv_sec) * 1000 + - (tv_usec - tcb->last_tv_usec) / 1000; - -#if 0 - _dbus_verbose (" interval = %lu elapsed = %lu\n", - interval, elapsed); -#endif + int msecs_remaining; - if (interval <= elapsed) + if (check_timeout (tv_sec, tv_usec, + tcb, &msecs_remaining)) { /* Save last callback time and fire this timeout */ tcb->last_tv_sec = tv_sec; tcb->last_tv_usec = tv_usec; #if 0 - _dbus_verbose (" invoking timeout\n"); + printf (" invoking timeout\n"); #endif (* tcb->function) (tcb->timeout, @@ -564,7 +610,6 @@ bus_loop_iterate (BusLoop *loop, } } - next_timeout: link = next; } } -- cgit