Overhaul the daemon uptime functions.
authorAndre Noll <maan@systemlinux.org>
Wed, 10 Aug 2011 22:01:11 +0000 (00:01 +0200)
committerAndre Noll <maan@systemlinux.org>
Sat, 17 Sep 2011 16:49:55 +0000 (18:49 +0200)
The public interface of daemon.c offers some helpers for maintaining
and printing the uptime of the service. This interface consists of
the "uptime" enumeration and the public functions server_uptime()
and uptime_str(). The former function takes an uptime enum which is
either 'UPTIME_GET' or 'UPTIME_SET'.

It is cleaner to avoid the enumeration and have two separate
functions for getting and setting the uptime, so this patch
replaces server_uptime() by two new functions get_server_uptime()
and set_server_start_time(), renames uptime_str() to
get_server_uptime_str() and gets rid of the uptime enum.

All three new functions take an optional struct timeval * type argument
for the common case where the caller already knows the current time, or
wishes to specify another time for whatever reason. This allows to save
one time() system call per scheduler loop in para_server since with
this patch status_refresh() can pass the global "now" pointer (which
us updated by the scheduler once per loop) to get_server_uptime().

audiod.c
audiod_command.c
command.c
daemon.c
daemon.h
server.c

index c78df5b..4864c85 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -1370,7 +1370,7 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
        log_welcome("para_audiod");
-       server_uptime(UPTIME_SET);
+       set_server_start_time(NULL);
        set_initial_status();
        FOR_EACH_SLOT(i)
                clear_slot(i);
index 1c22f58..dfb014a 100644 (file)
@@ -480,7 +480,7 @@ void audiod_status_dump(void)
                        free(new);
        }
 
-       new = uptime_str();
+       new = get_server_uptime_str(now);
        old = stat_item_values[SI_AUDIOD_UPTIME];
        if (!old || strcmp(old, new)) {
                free(old);
index 69bbbb7..3ba4310 100644 (file)
--- a/command.c
+++ b/command.c
@@ -108,7 +108,8 @@ static char *get_status(struct misc_meta_data *nmmd, int parser_friendly)
 {
        char mtime[30] = "";
        char *status, *flags; /* vss status info */
-       char *ut = uptime_str();
+       /* nobody updates our version of "now" */
+       char *ut = get_server_uptime_str(NULL);
        long offset = (nmmd->offset + 500) / 1000;
        struct timeval current_time;
        struct tm mtime_tm;
@@ -258,7 +259,7 @@ int com_si(struct stream_cipher_context *scc, int argc, __a_unused char * const
                sender_info = para_strcat(sender_info, info);
                free(info);
        }
-       ut = uptime_str();
+       ut = get_server_uptime_str(now);
        ret = sc_send_va_buffer(scc, "version: " GIT_VERSION "\n"
                "up: %s\nplayed: %u\n"
                "server_pid: %d\n"
index b7a0a32..ffdec4e 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -26,7 +26,6 @@ struct daemon {
        char *logfile_name;
        /** Current loglevel, see \ref daemon_set_loglevel(). */
        int loglevel;
-
        /** Used by \ref server_uptime() and \ref uptime_str(). */
        time_t startuptime;
        /** The file pointer if the logfile is open. */
@@ -277,43 +276,59 @@ void drop_privileges_or_die(const char *username, const char *groupname)
 }
 
 /**
- * Set/get the server uptime.
+ * Set the server startup time.
+ *
+ * \param startuptime The value to store as the server start time.
  *
- * \param set_or_get Chose one of the two modes.
+ * This should be called once on startup with \a startuptime either NULL or a
+ * pointer to a struct timeval which contains the current time. If \a
+ * startuptime is NULL, the server start time is set to the current time.
  *
- * This should be called at startup time with \a set_or_get equal to \p
- * UPTIME_SET which sets the uptime to zero.  Subsequent calls with \a
- * set_or_get equal to \p UPTIME_GET return the uptime.
+ * \sa time(2), difftime(3) \ref get_server_uptime(), \ref
+ * get_server_uptime_str().
+ */
+void set_server_start_time(const struct timeval *startuptime)
+{
+       if (startuptime)
+               me->startuptime = startuptime->tv_sec;
+       else
+               time(&me->startuptime);
+}
 
- * \return Zero if called with \a set_or_get equal to \p UPTIME_SET, the number
- * of seconds elapsed since the last reset otherwise.
+/**
+ * Get the server uptime.
+ *
+ * \param current_time The current time.
+ *
+ * The \a current_time pointer may be \p NULL. In this case the function
+ * obtains the current time from the system.
  *
- * \sa time(2), difftime(3).
+ * \return This returns the server uptime in seconds, i.e. the difference
+ * between the current time and the value stored previously via \ref
+ * set_server_start_time().
  */
-time_t server_uptime(enum uptime set_or_get)
+time_t get_server_uptime(const struct timeval *current_time)
 {
-       time_t now;
-       double diff;
+       time_t t;
 
-       if (set_or_get == UPTIME_SET) {
-               time(&me->startuptime);
-               return 0;
-       }
-       time(&now);
-       diff = difftime(now, me->startuptime);
-       return (time_t) diff;
+       if (current_time)
+               return current_time->tv_sec - me->startuptime;
+       time(&t);
+       return difftime(t, me->startuptime);
 }
 
 /**
- * Construct string containing uptime.
+ * Construct a string containing the current uptime.
+ *
+ * \param current_time See a \ref get_server_uptime().
  *
  * \return A dynamically allocated string of the form "days:hours:minutes".
  *
  * \sa server_uptime.
  */
-__malloc char *uptime_str(void)
+__malloc char *get_server_uptime_str(const struct timeval *current_time)
 {
-       long t = server_uptime(UPTIME_GET);
+       long t = get_server_uptime(current_time);
        return make_message("%li:%02li:%02li", t / 86400,
                (t / 3600) % 24, (t / 60) % 60);
 }
index 4e803bd..d5583f5 100644 (file)
--- a/daemon.h
+++ b/daemon.h
@@ -7,9 +7,9 @@ void daemon_close_log(void);
 void log_welcome(const char *whoami);
 void drop_privileges_or_die(const char *username, const char *groupname);
 /** used for server_uptime() */
-enum uptime {UPTIME_SET, UPTIME_GET};
-time_t server_uptime(enum uptime set_or_get);
-__malloc char *uptime_str(void);
+void set_server_start_time(const struct timeval *startuptime);
+time_t get_server_uptime(const struct timeval *current_time);
+__malloc char *get_server_uptime_str(const struct timeval *current_time);
 void daemon_set_logfile(char *logfile_name);
 void daemon_set_flag(unsigned flag);
 void daemon_clear_flag(unsigned flag);
index 5fec70b..15ae5c9 100644 (file)
--- a/server.c
+++ b/server.c
@@ -491,7 +491,7 @@ static void server_init(int argc, char **argv)
        init_ipc_or_die(); /* init mmd struct and mmd->lock */
        /* make sure, the global now pointer is uptodate */
        gettimeofday(now, NULL);
-       server_uptime(UPTIME_SET); /* reset server uptime */
+       set_server_start_time(now);
        init_user_list(user_list_file);
        /* become daemon */
        if (conf.daemon_given)
@@ -525,7 +525,7 @@ static void server_init(int argc, char **argv)
 static void status_refresh(void)
 {
        static int prev_uptime = -1, prev_events = -1;
-       int uptime = server_uptime(UPTIME_GET);
+       int uptime = get_server_uptime(now);
 
        if (prev_events != mmd->events)
                goto out;