PackageKit/0001-De-register-callbacks-on-PkClientHelper-finalize.patch
Adam Williamson 8631a4dc21 Backport several more fixes from master for libdnf compat
This should fix several bugs, including hopefully the 'runaway'
bug recently discussed on test@ list (I'm hoping this is fixed
by the 'Adapt for DnfAdvisory changes' patch).
2018-09-22 13:07:42 -07:00

277 lines
10 KiB
Diff

From 6b08de1e7578e32ec369148ff3f4d7f2e8c884af Mon Sep 17 00:00:00 2001
From: Robert Ancell <robert.ancell@canonical.com>
Date: Tue, 15 May 2018 13:07:40 +1200
Subject: [PATCH 01/13] De-register callbacks on PkClientHelper finalize.
These could otherwise trigger on a deleted object.
---
lib/packagekit-glib2/pk-client-helper.c | 83 ++++++++++++++++---------
1 file changed, 55 insertions(+), 28 deletions(-)
diff --git a/lib/packagekit-glib2/pk-client-helper.c b/lib/packagekit-glib2/pk-client-helper.c
index f3240afee..26ee12ec6 100644
--- a/lib/packagekit-glib2/pk-client-helper.c
+++ b/lib/packagekit-glib2/pk-client-helper.c
@@ -118,12 +118,16 @@ pk_client_helper_stop (PkClientHelper *client_helper, GError **error)
/* stop watching for events */
if (priv->io_channel_socket_listen_id > 0)
g_source_remove (priv->io_channel_socket_listen_id);
+ priv->io_channel_socket_listen_id = 0;
if (priv->io_channel_child_stdout_listen_id > 0)
g_source_remove (priv->io_channel_child_stdout_listen_id);
+ priv->io_channel_child_stdout_listen_id = 0;
if (priv->io_channel_child_stderr_listen_id > 0)
g_source_remove (priv->io_channel_child_stderr_listen_id);
+ priv->io_channel_child_stderr_listen_id = 0;
if (priv->io_channel_child_stdin_listen_id > 0)
g_source_remove (priv->io_channel_child_stdin_listen_id);
+ priv->io_channel_child_stdin_listen_id = 0;
}
/* kill process */
@@ -170,15 +174,16 @@ pk_client_helper_copy_stdout_cb (GIOChannel *source, GIOCondition condition, PkC
/* the helper process exited */
if ((condition & G_IO_HUP) > 0) {
g_debug ("helper process exited");
+ priv->io_channel_child_stdout_listen_id = 0;
status = g_io_channel_shutdown (priv->io_channel_child_stdout, FALSE, &error);
if (status != G_IO_STATUS_NORMAL) {
g_warning ("failed to shutdown channel: %s", error->message);
- return FALSE;
+ return G_SOURCE_REMOVE;
}
status = g_io_channel_shutdown (priv->io_channel_child_stderr, FALSE, &error);
if (status != G_IO_STATUS_NORMAL) {
g_warning ("failed to shutdown channel: %s", error->message);
- return FALSE;
+ return G_SOURCE_REMOVE;
}
if (priv->active_conn != NULL) {
ret = g_socket_close (priv->active_conn, &error);
@@ -188,7 +193,7 @@ pk_client_helper_copy_stdout_cb (GIOChannel *source, GIOCondition condition, PkC
g_object_unref (priv->active_conn);
priv->active_conn = NULL;
}
- return FALSE;
+ return G_SOURCE_REMOVE;
}
/* there is data to read */
@@ -198,10 +203,11 @@ pk_client_helper_copy_stdout_cb (GIOChannel *source, GIOCondition condition, PkC
status = g_io_channel_read_chars (source, data, 1024, &len, &error);
if (status == G_IO_STATUS_EOF) {
g_warning ("child closed unexpectedly");
- return FALSE;
+ priv->io_channel_child_stdout_listen_id = 0;
+ return G_SOURCE_REMOVE;
}
if (len == 0)
- return TRUE;
+ return G_SOURCE_CONTINUE;
/* write to socket */
data[len] = '\0';
@@ -209,16 +215,18 @@ pk_client_helper_copy_stdout_cb (GIOChannel *source, GIOCondition condition, PkC
status = g_io_channel_write_chars (priv->io_channel_socket, data, len, &written, &error);
if (status != G_IO_STATUS_NORMAL) {
g_warning ("failed to write to socket: %s", error->message);
- return FALSE;
+ priv->io_channel_child_stdout_listen_id = 0;
+ return G_SOURCE_REMOVE;
}
if (written != len) {
g_warning ("failed to write %" G_GSIZE_FORMAT " bytes, "
"only wrote %" G_GSIZE_FORMAT " bytes", len, written);
- return FALSE;
+ priv->io_channel_child_stdout_listen_id = 0;
+ return G_SOURCE_REMOVE;
}
g_debug ("wrote %" G_GSIZE_FORMAT " bytes to socket", written);
}
- return TRUE;
+ return G_SOURCE_CONTINUE;
}
/*
@@ -227,10 +235,11 @@ pk_client_helper_copy_stdout_cb (GIOChannel *source, GIOCondition condition, PkC
static gboolean
pk_client_helper_echo_stderr_cb (GIOChannel *source, GIOCondition condition, PkClientHelper *client_helper)
{
+ PkClientHelperPrivate *priv = client_helper->priv;
gchar data[1024];
gsize len = 0;
GIOStatus status;
- gboolean ret = TRUE;
+ gboolean ret = G_SOURCE_CONTINUE;
/* there is data to read */
if ((condition & G_IO_IN) == 0)
@@ -239,7 +248,8 @@ pk_client_helper_echo_stderr_cb (GIOChannel *source, GIOCondition condition, PkC
/* read data */
status = g_io_channel_read_chars (source, data, 1024, &len, NULL);
if (status == G_IO_STATUS_EOF) {
- ret = FALSE;
+ priv->io_channel_child_stderr_listen_id = 0;
+ ret = G_SOURCE_REMOVE;
goto out;
}
if (len == 0)
@@ -261,33 +271,39 @@ pk_client_helper_copy_conn_cb (GIOChannel *source, GIOCondition condition, PkCli
PkClientHelperPrivate *priv = client_helper->priv;
gchar data[1024];
gsize len = 0;
- GIOStatus status;
gsize written = 0;
- gboolean ret = TRUE;
g_autoptr(GError) error = NULL;
/* package manager is done processing a package */
if ((condition & G_IO_HUP) > 0) {
+ gboolean ret;
+
g_debug ("socket hung up");
ret = g_socket_close (priv->active_conn, &error);
if (!ret)
g_warning ("failed to close socket");
g_object_unref (priv->active_conn);
priv->active_conn = NULL;
- return FALSE;
+ priv->io_channel_child_stdin_listen_id = 0;
+ return G_SOURCE_REMOVE;
}
/* there is data to read */
if ((condition & G_IO_IN) > 0) {
+ GIOStatus status;
+
status = g_io_channel_read_chars (source, data, 1024, &len, &error);
- if (status == G_IO_STATUS_EOF)
- return FALSE;
+ if (status == G_IO_STATUS_EOF) {
+ priv->io_channel_child_stdin_listen_id = 0;
+ return G_SOURCE_REMOVE;
+ }
if (error != NULL) {
g_warning ("failed to read: %s", error->message);
- return FALSE;
+ priv->io_channel_child_stdin_listen_id = 0;
+ return G_SOURCE_REMOVE;
}
if (len == 0)
- return TRUE;
+ return G_SOURCE_CONTINUE;
/* write to child */
data[len] = '\0';
@@ -295,16 +311,18 @@ pk_client_helper_copy_conn_cb (GIOChannel *source, GIOCondition condition, PkCli
status = g_io_channel_write_chars (priv->io_channel_child_stdin, data, len, &written, &error);
if (status != G_IO_STATUS_NORMAL) {
g_warning ("failed to write to stdin: %s", error->message);
- return FALSE;
+ priv->io_channel_child_stdin_listen_id = 0;
+ return G_SOURCE_REMOVE;
}
if (written != len) {
g_warning ("failed to write %" G_GSIZE_FORMAT " bytes, "
"only wrote %" G_GSIZE_FORMAT " bytes", len, written);
- return FALSE;
+ priv->io_channel_child_stdin_listen_id = 0;
+ return G_SOURCE_REMOVE;
}
g_debug ("wrote %" G_GSIZE_FORMAT " bytes to stdin of %s", written, priv->argv[0]);
}
- return TRUE;
+ return G_SOURCE_CONTINUE;
}
/*
@@ -324,13 +342,13 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
/* delaying connection */
if (priv->active_conn != NULL)
- return TRUE;
+ return G_SOURCE_CONTINUE;
/* accept the connection request */
priv->active_conn = g_socket_accept (priv->socket, NULL, &error);
if (priv->active_conn == NULL) {
g_warning ("failed to accept socket: %s", error->message);
- return TRUE;
+ return G_SOURCE_CONTINUE;
}
g_debug ("accepting connection %i for socket %i",
g_socket_get_fd (priv->active_conn),
@@ -341,7 +359,7 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
&standard_input, &standard_output, &standard_error, &error);
if (!ret) {
g_warning ("failed to spawn: %s", error->message);
- return TRUE;
+ return G_SOURCE_CONTINUE;
}
g_debug ("started process %s with pid %i", priv->argv[0], priv->child_pid);
@@ -354,7 +372,7 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
status = g_io_channel_set_encoding (priv->io_channel_child_stdin, NULL, &error);
if (status != G_IO_STATUS_NORMAL) {
g_warning ("failed to set encoding: %s", error->message);
- return TRUE;
+ return G_SOURCE_CONTINUE;
}
g_io_channel_set_buffered (priv->io_channel_child_stdin, FALSE);
@@ -362,7 +380,7 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
status = g_io_channel_set_encoding (priv->io_channel_child_stdout, NULL, &error);
if (status != G_IO_STATUS_NORMAL) {
g_warning ("failed to set encoding: %s", error->message);
- return TRUE;
+ return G_SOURCE_CONTINUE;
}
g_io_channel_set_buffered (priv->io_channel_child_stdout, FALSE);
@@ -370,7 +388,7 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
status = g_io_channel_set_encoding (priv->io_channel_child_stderr, NULL, &error);
if (status != G_IO_STATUS_NORMAL) {
g_warning ("failed to set encoding: %s", error->message);
- return TRUE;
+ return G_SOURCE_CONTINUE;
}
g_io_channel_set_buffered (priv->io_channel_child_stderr, FALSE);
@@ -385,7 +403,7 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
status = g_io_channel_set_encoding (priv->io_channel_socket, NULL, &error);
if (status != G_IO_STATUS_NORMAL) {
g_warning ("failed to set encoding: %s", error->message);
- return TRUE;
+ return G_SOURCE_CONTINUE;
}
g_io_channel_set_buffered (priv->io_channel_socket, FALSE);
@@ -397,7 +415,7 @@ pk_client_helper_accept_connection_cb (GIOChannel *source, GIOCondition conditio
priv->io_channel_child_stderr_listen_id =
g_io_add_watch_full (priv->io_channel_child_stderr, G_PRIORITY_HIGH_IDLE, G_IO_IN,
(GIOFunc) pk_client_helper_echo_stderr_cb, client_helper, NULL);
- return TRUE;
+ return G_SOURCE_CONTINUE;
}
/**
@@ -533,6 +551,15 @@ pk_client_helper_finalize (GObject *object)
PkClientHelper *client_helper = PK_CLIENT_HELPER (object);
PkClientHelperPrivate *priv = client_helper->priv;
+ if (priv->io_channel_socket_listen_id > 0)
+ g_source_remove (priv->io_channel_socket_listen_id);
+ if (priv->io_channel_child_stdout_listen_id > 0)
+ g_source_remove (priv->io_channel_child_stdout_listen_id);
+ if (priv->io_channel_child_stderr_listen_id > 0)
+ g_source_remove (priv->io_channel_child_stderr_listen_id);
+ if (priv->io_channel_child_stdin_listen_id > 0)
+ g_source_remove (priv->io_channel_child_stdin_listen_id);
+
if (priv->socket_file != NULL)
g_object_unref (priv->socket_file);
if (priv->io_channel_socket != NULL)
--
2.19.0