From: Lennart Poettering Date: Mon, 25 Sep 2023 13:49:06 +0000 (+0200) Subject: varlink: add exit-on-idle logic for Varlink server X-Git-Tag: v255-rc1~305^2~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=47723340135f7d3fee0440647d4c3767fa3b4bf6;p=thirdparty%2Fsystemd.git varlink: add exit-on-idle logic for Varlink server This adds a logic that if enabled ensures sd_event_exit() is called whenever the varlink connection count hits zero. This is useful for implementing pure Varlink services (i.e. services whose only job is to serve Varlink requests), that shall run only as long as needed, i.e. as long as at least one request is being served. --- diff --git a/src/shared/varlink.c b/src/shared/varlink.c index f52c961ce5b..6015aed4cf0 100644 --- a/src/shared/varlink.c +++ b/src/shared/varlink.c @@ -234,6 +234,8 @@ struct VarlinkServer { unsigned connections_max; unsigned connections_per_uid_max; + + bool exit_on_idle; }; static const char* const varlink_state_table[_VARLINK_STATE_MAX] = { @@ -273,6 +275,7 @@ DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(varlink_state, VarlinkState); log_debug("%s: " fmt, varlink_server_description(s), ##__VA_ARGS__) static int varlink_format_queue(Varlink *v); +static void varlink_server_test_exit_on_idle(VarlinkServer *s); static const char *varlink_description(Varlink *v) { return (v ? v->description : NULL) ?: "varlink"; @@ -1654,6 +1657,7 @@ static void varlink_detach_server(Varlink *v) { if (saved_server->disconnect_callback) saved_server->disconnect_callback(saved_server, v, saved_server->userdata); + varlink_server_test_exit_on_idle(saved_server); varlink_server_unref(saved_server); varlink_unref(v); } @@ -3098,9 +3102,23 @@ int varlink_server_shutdown(VarlinkServer *s) { return 0; } +static void varlink_server_test_exit_on_idle(VarlinkServer *s) { + assert(s); + + if (s->exit_on_idle && s->event && s->n_connections == 0) + (void) sd_event_exit(s->event, 0); +} + +int varlink_server_set_exit_on_idle(VarlinkServer *s, bool b) { + assert_return(s, -EINVAL); + + s->exit_on_idle = b; + varlink_server_test_exit_on_idle(s); + return 0; +} + static int varlink_server_add_socket_event_source(VarlinkServer *s, VarlinkServerSocket *ss, int64_t priority) { _cleanup_(sd_event_source_unrefp) sd_event_source *es = NULL; - int r; assert(s); diff --git a/src/shared/varlink.h b/src/shared/varlink.h index d49a8510f04..143d82cabc6 100644 --- a/src/shared/varlink.h +++ b/src/shared/varlink.h @@ -170,6 +170,8 @@ sd_event *varlink_server_get_event(VarlinkServer *v); int varlink_server_shutdown(VarlinkServer *server); +int varlink_server_set_exit_on_idle(VarlinkServer *s, bool b); + unsigned varlink_server_connections_max(VarlinkServer *s); unsigned varlink_server_connections_per_uid_max(VarlinkServer *s);