diff options
author | Ondrej Kozina <okozina@redhat.com> | 2015-02-02 16:21:35 +0100 |
---|---|---|
committer | Ondrej Kozina <okozina@redhat.com> | 2015-04-01 11:01:21 +0200 |
commit | 63e32e6db60d21716679dfbdf5db5eaa2a5dde31 (patch) | |
tree | 6656137dc7a7189c51a61b05a75682853ac3924d | |
parent | 821385481bec6d78d6a58aa5622b89690e1f38c5 (diff) | |
download | lvm2-63e32e6db60d21716679dfbdf5db5eaa2a5dde31.tar.gz |
libdaemon: shutdown on idle draft
-rw-r--r-- | libdaemon/server/daemon-server.c | 24 | ||||
-rw-r--r-- | libdaemon/server/daemon-server.h | 7 |
2 files changed, 29 insertions, 2 deletions
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c index 5ccf4e98c..e3759ab2e 100644 --- a/libdaemon/server/daemon-server.c +++ b/libdaemon/server/daemon-server.c @@ -508,11 +508,18 @@ 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; 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 @@ -583,15 +590,28 @@ void daemon_start(daemon_state s) failed = 1; while (!_shutdown_requested && !failed) { + timeout.tv_sec = s.wait_secs; + timeout.tv_usec = 0; fd_set in; FD_ZERO(&in); FD_SET(s.socket_fd, &in); - if (select(FD_SETSIZE, &in, NULL, NULL, NULL) < 0 && errno != EINTR) + if (select(FD_SETSIZE, &in, NULL, NULL, s.idle ? &timeout : NULL) < 0 && errno != EINTR) perror("select error"); - if (FD_ISSET(s.socket_fd, &in)) + if (FD_ISSET(s.socket_fd, &in)) { + timeout_count = 0; if (!_shutdown_requested && !handle_connect(s)) ERROR(&s, "Failed to handle a client connection."); + } + 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) { + INFO(&s, "Maximum number of timeouts exceeded"); + break; + } + } } INFO(&s, "%s waiting for client threads to finish", s.name); diff --git a/libdaemon/server/daemon-server.h b/libdaemon/server/daemon-server.h index a7673d455..e507acae1 100644 --- a/libdaemon/server/daemon-server.h +++ b/libdaemon/server/daemon-server.h @@ -64,6 +64,8 @@ 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]; @@ -99,6 +101,11 @@ typedef struct daemon_state { log_state *log; 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 */ } daemon_state; typedef struct thread_state { |