summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Kozina <okozina@redhat.com>2015-02-11 15:19:41 +0100
committerOndrej Kozina <okozina@redhat.com>2015-04-01 11:01:21 +0200
commit2233c916b087afab0f6f98ccb0fee79c2feea9f2 (patch)
treebea05c52810d5f7d5f9839cbc3936fbff9b4da62
parent63e32e6db60d21716679dfbdf5db5eaa2a5dde31 (diff)
downloadlvm2-2233c916b087afab0f6f98ccb0fee79c2feea9f2.tar.gz
libdaemon: add support for 'exit when idle'
-rw-r--r--libdaemon/server/daemon-server.c36
-rw-r--r--libdaemon/server/daemon-server.h22
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