diff options
author | Ondrej Kozina <okozina@redhat.com> | 2015-02-11 15:19:41 +0100 |
---|---|---|
committer | Ondrej Kozina <okozina@redhat.com> | 2015-04-01 11:01:21 +0200 |
commit | 2233c916b087afab0f6f98ccb0fee79c2feea9f2 (patch) | |
tree | bea05c52810d5f7d5f9839cbc3936fbff9b4da62 | |
parent | 63e32e6db60d21716679dfbdf5db5eaa2a5dde31 (diff) | |
download | lvm2-2233c916b087afab0f6f98ccb0fee79c2feea9f2.tar.gz |
libdaemon: add support for 'exit when idle'
-rw-r--r-- | libdaemon/server/daemon-server.c | 36 | ||||
-rw-r--r-- | libdaemon/server/daemon-server.h | 22 |
2 files changed, 40 insertions, 18 deletions
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c index e3759ab2e..4a0d5cf00 100644 --- a/libdaemon/server/daemon-server.c +++ b/libdaemon/server/daemon-server.c @@ -80,6 +80,24 @@ static void _exit_handler(int sig __attribute__((unused))) # include <stdio.h> +static inline int _is_idle(daemon_state s) +{ + return _systemd_activation && s.idle && s.idle->is_idle && !s.threads->next; +} + +static inline struct timeval *_get_timeout(daemon_state s) +{ + return (_systemd_activation && s.idle) ? s.idle->ptimeout : NULL; +} + +static inline void _reset_timeout(daemon_state s) +{ + if (s.idle) { + s.idle->ptimeout->tv_sec = 1; + s.idle->ptimeout->tv_usec = 0; + } +} + static int _set_oom_adj(const char *oom_adj_path, int val) { FILE *fp; @@ -508,18 +526,12 @@ static void reap(daemon_state s, int waiting) } } -static inline int no_clients(daemon_state s) -{ - return s.threads->next == NULL; -} - void daemon_start(daemon_state s) { - struct timeval timeout; + unsigned timeout_count; int failed = 0; log_state _log = { { 0 } }; thread_state _threads = { .next = NULL }; - unsigned timeout_count = 0; /* * Switch to C locale to avoid reading large locale-archive file used by @@ -590,12 +602,11 @@ void daemon_start(daemon_state s) failed = 1; while (!_shutdown_requested && !failed) { - timeout.tv_sec = s.wait_secs; - timeout.tv_usec = 0; + _reset_timeout(s); fd_set in; FD_ZERO(&in); FD_SET(s.socket_fd, &in); - if (select(FD_SETSIZE, &in, NULL, NULL, s.idle ? &timeout : NULL) < 0 && errno != EINTR) + if (select(FD_SETSIZE, &in, NULL, NULL, _get_timeout(s)) < 0 && errno != EINTR) perror("select error"); if (FD_ISSET(s.socket_fd, &in)) { timeout_count = 0; @@ -606,8 +617,9 @@ void daemon_start(daemon_state s) reap(s, 0); /* s.idle == NULL equals no shutdown on timeout */ - if (s.idle && no_clients(s) && s.idle(s.private)) { - if (++timeout_count >= s.max_timeouts) { + if (_is_idle(s)) { + DEBUGLOG(&s, "Timeout No. %d", timeout_count + 1); + if (++timeout_count >= _get_max_timeouts(s)) { INFO(&s, "Maximum number of timeouts exceeded"); break; } diff --git a/libdaemon/server/daemon-server.h b/libdaemon/server/daemon-server.h index e507acae1..e6839c9d6 100644 --- a/libdaemon/server/daemon-server.h +++ b/libdaemon/server/daemon-server.h @@ -35,8 +35,17 @@ typedef struct { struct buffer buffer; } response; +struct timeval; + +typedef struct { + volatile unsigned is_idle; + unsigned max_timeouts; + struct timeval *ptimeout; +} daemon_idle; + struct daemon_state; + /* * Craft a simple reply, without the need to construct a config_tree. See * daemon_send_simple in daemon-client.h for the description of the parameters. @@ -64,8 +73,6 @@ static inline const char *daemon_request_str(request r, const char *path, const */ typedef response (*handle_request)(struct daemon_state s, client_handle h, request r); -typedef int (*is_idle_fn)(void *private); - typedef struct { uint32_t log_config[32]; void *backend_state[32]; @@ -102,10 +109,8 @@ typedef struct daemon_state { struct thread_state *threads; void *private; /* the global daemon state */ - /* timeouts handling */ - is_idle_fn idle; /* daemon specific function, NULL == no shutdown on timeout */ - unsigned max_timeouts; /* max allowed timeouts */ - unsigned wait_secs; /* secs to wait in select loop */ + /* suport for shutdown on idle */ + daemon_idle *idle; } daemon_state; typedef struct thread_state { @@ -173,4 +178,9 @@ void daemon_log_enable(log_state *s, int outlet, int type, int enable); */ int daemon_log_parse(log_state *s, int outlet, const char *types, int enable); +static inline unsigned _get_max_timeouts(daemon_state s) +{ + return s.idle ? s.idle->max_timeouts : 0; +} + #endif |