[Spice-devel] [RFC spice-vdagent 03/18] vdagentd: use GMainLoop
Jakub Janků
jjanku at redhat.com
Tue Aug 14 18:53:37 UTC 2018
This is purely a preparatory patch as it renders
the vdagentd non-functional.
Remove main while loop with FD polling.
udscs, virtio-port and session-info will be integrated
into the GMainLoop in the following commits.
Use g_unix_signal_add() to handle SIGINT, SIGHUP, SIGTERM.
SIGQUIT handling is not supported by GLib.
---
src/vdagentd/vdagentd.c | 129 ++++++++++++++--------------------------
1 file changed, 44 insertions(+), 85 deletions(-)
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index d88bbc7..8abc63c 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -31,10 +31,9 @@
#include <errno.h>
#include <signal.h>
#include <syslog.h>
-#include <sys/select.h>
#include <sys/stat.h>
#include <spice/vd_agent.h>
-#include <glib.h>
+#include <glib-unix.h>
#ifdef WITH_SYSTEMD_SOCKET_ACTIVATION
#include <systemd/sd-daemon.h>
@@ -82,11 +81,12 @@ static const char *active_session = NULL;
static unsigned int session_count = 0;
static struct udscs_connection *active_session_conn = NULL;
static int agent_owns_clipboard[256] = { 0, };
-static int quit = 0;
static int retval = 0;
static int client_connected = 0;
static int max_clipboard = -1;
+static GMainLoop *loop;
+
/* utility functions */
static void virtio_msg_uint32_to_le(uint8_t *_msg, uint32_t size, uint32_t offset)
{
@@ -175,7 +175,7 @@ void do_client_mouse(struct vdagentd_uinput **uinputp, VDAgentMouseState *mouse)
if (!*uinputp) {
syslog(LOG_CRIT, "Fatal uinput error");
retval = 1;
- quit = 1;
+ g_main_loop_quit(loop);
}
}
}
@@ -588,6 +588,33 @@ static int virtio_port_read_complete(
return 0;
}
+static void virtio_port_disconnect_cb(struct vdagent_virtio_port *vport,
+ gboolean by_user)
+{
+ virtio_port = NULL;
+
+ if (!g_main_loop_is_running(loop))
+ return;
+
+ if (by_user == FALSE) {
+ /* virtio_port was destroyed because of an internal error */
+ gboolean old_client_connected = client_connected;
+ syslog(LOG_CRIT, "AIIEEE lost spice client connection, reconnecting");
+ virtio_port = vdagent_virtio_port_create(portdev,
+ virtio_port_read_complete,
+ virtio_port_disconnect_cb);
+ if (virtio_port == NULL) {
+ syslog(LOG_CRIT, "Fatal error opening vdagent virtio channel");
+ retval = 1;
+ g_main_loop_quit(loop);
+ return;
+ }
+ do_client_disconnect();
+ client_connected = old_client_connected;
+ } else if (only_once)
+ g_main_loop_quit(loop);
+}
+
static void virtio_write_clipboard(uint8_t selection, uint32_t msg_type,
uint32_t data_type, uint8_t *data, uint32_t data_size)
{
@@ -727,7 +754,7 @@ static void check_xorg_resolution(void)
if (!uinput) {
syslog(LOG_CRIT, "Fatal uinput error");
retval = 1;
- quit = 1;
+ g_main_loop_quit(loop);
return;
}
@@ -735,11 +762,11 @@ static void check_xorg_resolution(void)
syslog(LOG_INFO, "opening vdagent virtio channel");
virtio_port = vdagent_virtio_port_create(portdev,
virtio_port_read_complete,
- NULL);
+ virtio_port_disconnect_cb);
if (!virtio_port) {
syslog(LOG_CRIT, "Fatal error opening vdagent virtio channel");
retval = 1;
- quit = 1;
+ g_main_loop_quit(loop);
return;
}
send_capabilities(virtio_port, 1);
@@ -992,76 +1019,10 @@ static void daemonize(void)
}
}
-static void main_loop(void)
+static gboolean signal_handler(gpointer user_data)
{
- fd_set readfds, writefds;
- int n, nfds;
- int ck_fd = 0;
- int once = 0;
-
- while (!quit) {
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
-
- nfds = udscs_server_fill_fds(server, &readfds, &writefds);
- n = vdagent_virtio_port_fill_fds(virtio_port, &readfds, &writefds);
- if (n >= nfds)
- nfds = n + 1;
-
- if (session_info) {
- ck_fd = session_info_get_fd(session_info);
- FD_SET(ck_fd, &readfds);
- if (ck_fd >= nfds)
- nfds = ck_fd + 1;
- }
-
- n = select(nfds, &readfds, &writefds, NULL, NULL);
- if (n == -1) {
- if (errno == EINTR)
- continue;
- syslog(LOG_CRIT, "Fatal error select: %m");
- retval = 1;
- break;
- }
-
- udscs_server_handle_fds(server, &readfds, &writefds);
-
- if (virtio_port) {
- once = 1;
- vdagent_virtio_port_handle_fds(&virtio_port, &readfds, &writefds);
- if (!virtio_port) {
- int old_client_connected = client_connected;
- syslog(LOG_CRIT,
- "AIIEEE lost spice client connection, reconnecting");
- virtio_port = vdagent_virtio_port_create(portdev,
- virtio_port_read_complete,
- NULL);
- if (!virtio_port) {
- syslog(LOG_CRIT,
- "Fatal error opening vdagent virtio channel");
- retval = 1;
- break;
- }
- do_client_disconnect();
- client_connected = old_client_connected;
- }
- }
- else if (only_once && once)
- {
- syslog(LOG_INFO, "Exiting after one client session.");
- break;
- }
-
- if (session_info && FD_ISSET(ck_fd, &readfds)) {
- active_session = session_info_get_active_session(session_info);
- update_active_session_connection(NULL);
- }
- }
-}
-
-static void quit_handler(int sig)
-{
- quit = 1;
+ g_main_loop_quit(loop);
+ return G_SOURCE_REMOVE;
}
static gboolean parse_debug_level_cb(const gchar *option_name,
@@ -1115,7 +1076,6 @@ int main(int argc, char *argv[])
{
GOptionContext *context;
GError *err = NULL;
- struct sigaction act;
gboolean own_socket = TRUE;
context = g_option_context_new(NULL);
@@ -1138,13 +1098,9 @@ int main(int argc, char *argv[])
if (uinput_device == NULL)
uinput_device = g_strdup(DEFAULT_UINPUT_DEVICE);
- memset(&act, 0, sizeof(act));
- act.sa_flags = SA_RESTART;
- act.sa_handler = quit_handler;
- sigaction(SIGINT, &act, NULL);
- sigaction(SIGHUP, &act, NULL);
- sigaction(SIGTERM, &act, NULL);
- sigaction(SIGQUIT, &act, NULL);
+ g_unix_signal_add(SIGINT, signal_handler, NULL);
+ g_unix_signal_add(SIGHUP, signal_handler, NULL);
+ g_unix_signal_add(SIGTERM, signal_handler, NULL);
openlog("spice-vdagentd", do_daemonize ? 0 : LOG_PERROR, LOG_USER);
@@ -1214,7 +1170,9 @@ int main(int argc, char *argv[])
syslog(LOG_WARNING, "no session info, max 1 session agent allowed");
active_xfers = g_hash_table_new(g_direct_hash, g_direct_equal);
- main_loop();
+
+ loop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(loop);
release_clipboards();
@@ -1223,6 +1181,7 @@ int main(int argc, char *argv[])
vdagent_virtio_port_destroy(&virtio_port);
session_info_destroy(session_info);
udscs_destroy_server(server);
+ g_main_loop_unref(loop);
/* leave the socket around if it was provided by systemd */
if (own_socket) {
--
2.17.1
More information about the Spice-devel
mailing list