summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Kozina <okozina@redhat.com>2015-02-02 16:21:35 +0100
committerOndrej Kozina <okozina@redhat.com>2015-04-01 11:01:21 +0200
commit63e32e6db60d21716679dfbdf5db5eaa2a5dde31 (patch)
tree6656137dc7a7189c51a61b05a75682853ac3924d
parent821385481bec6d78d6a58aa5622b89690e1f38c5 (diff)
downloadlvm2-63e32e6db60d21716679dfbdf5db5eaa2a5dde31.tar.gz
libdaemon: shutdown on idle draft
-rw-r--r--libdaemon/server/daemon-server.c24
-rw-r--r--libdaemon/server/daemon-server.h7
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 {