From 2874bb5cc706267e5d4b215e27097992146d6193 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Fri, 20 Nov 2020 18:46:32 -0800 Subject: [PATCH] Backport #2605 for #2600, seems to help RHBZ #1896540 --- ...when-called-from-threads-without-a-c.patch | 526 ++++++++++++++++++ fwupd.spec | 10 +- 2 files changed, 534 insertions(+), 2 deletions(-) create mode 100644 0001-Fix-sync-method-when-called-from-threads-without-a-c.patch diff --git a/0001-Fix-sync-method-when-called-from-threads-without-a-c.patch b/0001-Fix-sync-method-when-called-from-threads-without-a-c.patch new file mode 100644 index 0000000..7e3dc26 --- /dev/null +++ b/0001-Fix-sync-method-when-called-from-threads-without-a-c.patch @@ -0,0 +1,526 @@ +From 1a14d2be009ada386eba65ccd78feaa27853f109 Mon Sep 17 00:00:00 2001 +From: Richard Hughes +Date: Thu, 19 Nov 2020 13:19:54 +0000 +Subject: [PATCH] Fix sync method when called from threads without a context + +Set the thread-default context for the current thread before performing the +async operation. + +Hopefully fixes https://github.com/fwupd/fwupd/issues/2600 +--- + libfwupd/fwupd-client-sync.c | 80 +++++++++++++++++++++++++++++++++++- + 1 file changed, 79 insertions(+), 1 deletion(-) + +diff --git a/libfwupd/fwupd-client-sync.c b/libfwupd/fwupd-client-sync.c +index 56068f6b..dab0a751 100644 +--- a/libfwupd/fwupd-client-sync.c ++++ b/libfwupd/fwupd-client-sync.c +@@ -21,6 +21,7 @@ typedef struct { + gchar *str; + GError *error; + GPtrArray *array; ++ GMainContext *context; + GMainLoop *loop; + GVariant *val; + GHashTable *hash; +@@ -45,6 +46,7 @@ fwupd_client_helper_free (FwupdClientHelper *helper) + g_object_unref (helper->device); + g_free (helper->str); + g_main_loop_unref (helper->loop); ++ g_main_context_unref (helper->context); + g_free (helper); + } + +@@ -53,7 +55,8 @@ fwupd_client_helper_new (void) + { + FwupdClientHelper *helper; + helper = g_new0 (FwupdClientHelper, 1); +- helper->loop = g_main_loop_new (NULL, FALSE); ++ helper->context = g_main_context_new (); ++ helper->loop = g_main_loop_new (helper->context, FALSE); + return helper; + } + +@@ -94,8 +97,10 @@ fwupd_client_connect (FwupdClient *self, GCancellable *cancellable, GError **err + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_connect_async (self, cancellable, fwupd_client_connect_cb, helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -137,9 +142,11 @@ fwupd_client_get_devices (FwupdClient *self, GCancellable *cancellable, GError * + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_devices_async (self, cancellable, + fwupd_client_get_devices_cb, helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -181,9 +188,11 @@ fwupd_client_get_plugins (FwupdClient *self, GCancellable *cancellable, GError * + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_plugins_async (self, cancellable, + fwupd_client_get_plugins_cb, helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -225,9 +234,11 @@ fwupd_client_get_history (FwupdClient *self, GCancellable *cancellable, GError * + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_history_async (self, cancellable, + fwupd_client_get_history_cb, helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -272,9 +283,11 @@ fwupd_client_get_releases (FwupdClient *self, const gchar *device_id, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_releases_async (self, device_id, cancellable, + fwupd_client_get_releases_cb, helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -319,9 +332,11 @@ fwupd_client_get_downgrades (FwupdClient *self, const gchar *device_id, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_downgrades_async (self, device_id, cancellable, + fwupd_client_get_downgrades_cb, helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -366,9 +381,11 @@ fwupd_client_get_upgrades (FwupdClient *self, const gchar *device_id, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_upgrades_async (self, device_id, cancellable, + fwupd_client_get_upgrades_cb, helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -415,11 +432,13 @@ fwupd_client_get_details_bytes (FwupdClient *self, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_details_bytes_async (self, bytes, + cancellable, + fwupd_client_get_details_bytes_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -473,10 +492,12 @@ fwupd_client_get_details (FwupdClient *self, + istr = fwupd_unix_input_stream_from_fn (filename, error); + if (istr == NULL) + return NULL; ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_details_stream_async (self, istr, cancellable, + fwupd_client_get_details_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -530,10 +551,12 @@ fwupd_client_verify (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_verify_async (self, device_id, cancellable, + fwupd_client_verify_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -580,10 +603,12 @@ fwupd_client_verify_update (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_verify_update_async (self, device_id, cancellable, + fwupd_client_verify_update_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -630,10 +655,12 @@ fwupd_client_unlock (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_unlock_async (self, device_id, cancellable, + fwupd_client_unlock_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -683,11 +710,13 @@ fwupd_client_modify_config (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_modify_config_async (self, key, value, + cancellable, + fwupd_client_modify_config_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -735,11 +764,13 @@ fwupd_client_activate (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_activate_async (self, device_id, + cancellable, + fwupd_client_activate_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -786,11 +817,13 @@ fwupd_client_clear_results (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_clear_results_async (self, device_id, + cancellable, + fwupd_client_clear_results_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -835,9 +868,11 @@ fwupd_client_get_results (FwupdClient *self, const gchar *device_id, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_results_async (self, device_id, cancellable, + fwupd_client_get_results_cb, helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->device == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -881,10 +916,12 @@ fwupd_client_get_host_security_attrs (FwupdClient *self, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_host_security_attrs_async (self, cancellable, + fwupd_client_get_host_security_attrs_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -931,10 +968,12 @@ fwupd_client_get_device_by_id (FwupdClient *self, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_device_by_id_async (self, device_id, cancellable, + fwupd_client_get_device_by_id_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->device == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -980,10 +1019,12 @@ fwupd_client_get_devices_by_guid (FwupdClient *self, const gchar *guid, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_devices_by_guid_async (self, guid, cancellable, + fwupd_client_get_devices_by_guid_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -1044,11 +1085,13 @@ fwupd_client_install (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_install_stream_async (self, device_id, istr, filename, + install_flags, cancellable, + fwupd_client_install_fd_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -1107,11 +1150,13 @@ fwupd_client_install_bytes (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_install_bytes_async (self, device_id, bytes, install_flags, + cancellable, + fwupd_client_install_bytes_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -1162,11 +1207,13 @@ fwupd_client_install_release (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_install_release_async (self, device, release, + install_flags, cancellable, + fwupd_client_install_release_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -1236,10 +1283,12 @@ fwupd_client_update_metadata (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_update_metadata_stream_async (self, remote_id, istr, istr_sig, cancellable, + fwupd_client_update_metadata_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -1304,11 +1353,13 @@ fwupd_client_update_metadata_bytes (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_update_metadata_bytes_async (self, remote_id, metadata, signature, + cancellable, + fwupd_client_update_metadata_bytes_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -1353,10 +1404,13 @@ fwupd_client_refresh_remote (FwupdClient *self, + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + ++ /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_refresh_remote_async (self, remote, cancellable, + fwupd_client_refresh_remote_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -1411,11 +1465,13 @@ fwupd_client_modify_remote (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_modify_remote_async (self, remote_id, key, value, + cancellable, + fwupd_client_modify_remote_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -1459,10 +1515,12 @@ fwupd_client_get_report_metadata (FwupdClient *self, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_report_metadata_async (self, cancellable, + fwupd_client_get_report_metadata_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->hash == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -1518,11 +1576,13 @@ fwupd_client_modify_device (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_modify_device_async (self, device_id, key, value, + cancellable, + fwupd_client_modify_device_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -1564,9 +1624,11 @@ fwupd_client_get_remotes (FwupdClient *self, GCancellable *cancellable, GError * + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_remotes_async (self, cancellable, + fwupd_client_get_remotes_cb, helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -1667,10 +1729,12 @@ fwupd_client_get_approved_firmware (FwupdClient *self, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_approved_firmware_async (self, cancellable, + fwupd_client_get_approved_firmware_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -1722,10 +1786,12 @@ fwupd_client_set_approved_firmware (FwupdClient *self, + g_ptr_array_add (array, g_strdup (checksums[i])); + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_set_approved_firmware_async (self, array, cancellable, + fwupd_client_set_approved_firmware_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -1770,10 +1836,12 @@ fwupd_client_get_blocked_firmware (FwupdClient *self, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_get_blocked_firmware_async (self, cancellable, + fwupd_client_get_blocked_firmware_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->array == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -1829,10 +1897,12 @@ fwupd_client_set_blocked_firmware (FwupdClient *self, + g_ptr_array_add (array, g_strdup (checksums[i])); + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_set_blocked_firmware_async (self, array, cancellable, + fwupd_client_set_blocked_firmware_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -1882,10 +1952,12 @@ fwupd_client_set_feature_flags (FwupdClient *self, + return FALSE; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_set_feature_flags_async (self, feature_flags, cancellable, + fwupd_client_set_feature_flags_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (!helper->ret) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return FALSE; +@@ -1934,10 +2006,12 @@ fwupd_client_self_sign (FwupdClient *self, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_self_sign_async (self, value, flags, cancellable, + fwupd_client_self_sign_cb, + helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->str == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -1988,9 +2062,11 @@ fwupd_client_download_bytes (FwupdClient *self, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_download_bytes_async (self, url, flags, cancellable, + fwupd_client_download_bytes_cb, helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->bytes == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +@@ -2095,9 +2171,11 @@ fwupd_client_upload_bytes (FwupdClient *self, + return NULL; + + /* call async version and run loop until complete */ ++ g_main_context_push_thread_default (helper->context); + fwupd_client_upload_bytes_async (self, url, payload, signature, flags, cancellable, + fwupd_client_upload_bytes_cb, helper); + g_main_loop_run (helper->loop); ++ g_main_context_pop_thread_default (helper->context); + if (helper->bytes == NULL) { + g_propagate_error (error, g_steal_pointer (&helper->error)); + return NULL; +-- +2.29.2 + diff --git a/fwupd.spec b/fwupd.spec index 93e1f0e..b16eeb7 100644 --- a/fwupd.spec +++ b/fwupd.spec @@ -49,10 +49,13 @@ Summary: Firmware update daemon Name: fwupd Version: 1.5.1 -Release: 1%{?dist} +Release: 2%{?dist} License: LGPLv2+ URL: https://github.com/fwupd/fwupd Source0: http://people.freedesktop.org/~hughsient/releases/%{name}-%{version}.tar.xz +# Backport of https://github.com/fwupd/fwupd/pull/2605 +# Fixes https://github.com/fwupd/fwupd/issues/2600 +Patch0: 0001-Fix-sync-method-when-called-from-threads-without-a-c.patch BuildRequires: gettext BuildRequires: glib2-devel >= %{glib2_version} @@ -484,7 +487,10 @@ mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/cache/fwupd %endif %changelog -* Mon Nov 01 2020 Richard Hughes 1.5.2-1 +* Fri Nov 20 2020 Adam Williamson - 1.5.1-2 +- Backport #2605 for #2600, seems to help RHBZ #1896540 + +* Mon Nov 01 2020 Richard Hughes 1.5.1-1 - New upstream release - Delete unused EFI variables when deploying firmware - Fix probe warning for the Logitech Unifying device