]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
src: ensure GSource background unref happens in correct event loop
authorDaniel P. Berrangé <berrange@redhat.com>
Tue, 16 Mar 2021 16:26:06 +0000 (16:26 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Wed, 17 Mar 2021 09:16:05 +0000 (09:16 +0000)
The g_idle_add function adds a callback to the primary GMainContext.

To workaround the GSource unref bugs, we need to add our callbacks
to the GMainContext that is associated with the GSource being
unref'd. Thus code using the per-VM virEventThread must use its
private GMainContext.

Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
meson.build
src/libvirt_glib_crash_workaround.syms [deleted file]
src/libvirt_private.syms
src/meson.build
src/qemu/qemu_agent.c
src/qemu/qemu_monitor.c
src/util/glibcompat.c
src/util/glibcompat.h
src/util/vireventglib.c

index 69a7b4c88e7e2bfd14c4fee7a96af8aaa8d407ec..ea93a2a8ecb93979dbda225bc6b59005a4eade98 100644 (file)
@@ -1049,9 +1049,6 @@ if host_machine.system() == 'windows'
 else
   gio_dep = dependency('gio-unix-2.0', version: '>=' + glib_version)
 endif
-# GLib event loop race workaround in glibcompat.h, remove when minimum required
-# glib is >= 2.64.0
-glib_crash_workaround = glib_dep.version().version_compare('<2.64.0')
 glib_dep = declare_dependency(
   dependencies: [ glib_dep, gobject_dep, gio_dep ],
 )
diff --git a/src/libvirt_glib_crash_workaround.syms b/src/libvirt_glib_crash_workaround.syms
deleted file mode 100644 (file)
index 249058b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Private symbols specific for pre-2.64.0 GLib workaround
-#
-
-# util/glibcompat.h
-virEventGLibSourceUnrefIdle;
-
-# Let emacs know we want case-insensitive sorting
-# Local Variables:
-# sort-fold-case: t
-# End:
index 767d665613bdced6a0dacf63fef0590457f649fd..526dcee11a4945b6133697cc2d918550dd905406 100644 (file)
@@ -1733,6 +1733,7 @@ virStorageSourceUpdatePhysicalSize;
 # util/glibcompat.h
 vir_g_canonicalize_filename;
 vir_g_fsync;
+vir_g_source_unref;
 vir_g_strdup_printf;
 vir_g_strdup_vprintf;
 
index 70a5a83eea3eda471a071cb121e33a59c21d0873..c7ff9e978cd1c948f625cfba73900fa13f0292ec 100644 (file)
@@ -124,13 +124,6 @@ else
   sym_files += 'libvirt_libssh2.syms'
 endif
 
-if glib_crash_workaround
-  used_sym_files += 'libvirt_glib_crash_workaround.syms'
-else
-  sym_files += 'libvirt_glib_crash_workaround.syms'
-endif
-
-
 # variables filled by subdirectories
 
 libvirt_libs = []
index 01ba2c78c1c201e2858a8b9e83b652ecec30446c..787a7bb41c4e3e2c8353cc724e55f3e68688441d 100644 (file)
@@ -533,7 +533,7 @@ qemuAgentUnregister(qemuAgentPtr agent)
 {
     if (agent->watch) {
         g_source_destroy(agent->watch);
-        g_vir_source_unref_safe(agent->watch);
+        vir_g_source_unref(agent->watch, agent->context);
         agent->watch = NULL;
     }
 }
index b4f2641504f8276ae8c354aa950f433c55e18059..f6cd9d9edadcc579e718b7bc405e3608da4737f5 100644 (file)
@@ -862,7 +862,7 @@ qemuMonitorUnregister(qemuMonitorPtr mon)
 {
     if (mon->watch) {
         g_source_destroy(mon->watch);
-        g_vir_source_unref_safe(mon->watch);
+        vir_g_source_unref(mon->watch, mon->context);
         mon->watch = NULL;
     }
 }
index fe19ffa87b3fe789e5c22db7e6c87fc04ba69347..eb6dcc0111b9bb968a6e45a659cc45f31d297df0 100644 (file)
@@ -231,9 +231,14 @@ vir_g_strdup_vprintf(const char *msg, va_list args)
  *
  * Drop when min glib >= 2.64.0
  */
-#if GLIB_CHECK_VERSION(2, 64, 0) != TRUE
+#if GLIB_CHECK_VERSION(2, 64, 0)
+void vir_g_source_unref(GSource *src, GMainContext *ctx G_GNUC_UNUSED)
+{
+    g_source_unref(src);
+}
+#else
 
-gboolean
+static gboolean
 virEventGLibSourceUnrefIdle(gpointer data)
 {
     GSource *src = data;
@@ -243,4 +248,15 @@ virEventGLibSourceUnrefIdle(gpointer data)
     return FALSE;
 }
 
+void vir_g_source_unref(GSource *src, GMainContext *ctx)
+{
+    GSource *idle = g_idle_source_new();
+
+    g_source_set_callback(idle, virEventGLibSourceUnrefIdle, src, NULL);
+
+    g_source_attach(idle, ctx);
+
+    g_source_unref(idle);
+}
+
 #endif
index 9c528432742ba184d2e45a9b175649b2041508df..697687b967f8416e6d7b3a4ae57520576b97851b 100644 (file)
@@ -85,13 +85,4 @@ char *vir_g_strdup_vprintf(const char *msg, va_list args)
 #undef g_fsync
 #define g_fsync vir_g_fsync
 
-/* Drop when min glib >= 2.64.0 */
-#if GLIB_CHECK_VERSION(2, 64, 0)
-# define g_vir_source_unref_safe(source) g_source_unref(source)
-#else
-# define g_vir_source_unref_safe(source) g_idle_add(virEventGLibSourceUnrefIdle, source)
-
-gboolean
-virEventGLibSourceUnrefIdle(gpointer data);
-
-#endif
+void vir_g_source_unref(GSource *src, GMainContext *ctx);
index 88e3ec6d5dbb84225fc0423e498384d451fe5bff..f3e5a344b058029391c1391f2b867de6398cd6cb 100644 (file)
@@ -214,7 +214,7 @@ virEventGLibHandleUpdate(int watch,
         if (data->source != NULL) {
             VIR_DEBUG("Removed old handle source=%p", data->source);
             g_source_destroy(data->source);
-            g_vir_source_unref_safe(data->source);
+            vir_g_source_unref(data->source, NULL);
         }
 
         data->source = virEventGLibAddSocketWatch(
@@ -228,7 +228,7 @@ virEventGLibHandleUpdate(int watch,
 
         VIR_DEBUG("Removed old handle source=%p", data->source);
         g_source_destroy(data->source);
-        g_vir_source_unref_safe(data->source);
+        vir_g_source_unref(data->source, NULL);
         data->source = NULL;
         data->events = 0;
     }
@@ -277,7 +277,7 @@ virEventGLibHandleRemove(int watch)
 
     if (data->source != NULL) {
         g_source_destroy(data->source);
-        g_vir_source_unref_safe(data->source);
+        vir_g_source_unref(data->source, NULL);
         data->source = NULL;
         data->events = 0;
     }
@@ -410,7 +410,7 @@ virEventGLibTimeoutUpdate(int timer,
     if (interval >= 0) {
         if (data->source != NULL) {
             g_source_destroy(data->source);
-            g_vir_source_unref_safe(data->source);
+            vir_g_source_unref(data->source, NULL);
         }
 
         data->interval = interval;
@@ -420,7 +420,7 @@ virEventGLibTimeoutUpdate(int timer,
             goto cleanup;
 
         g_source_destroy(data->source);
-        g_vir_source_unref_safe(data->source);
+        vir_g_source_unref(data->source, NULL);
         data->source = NULL;
     }
 
@@ -469,7 +469,7 @@ virEventGLibTimeoutRemove(int timer)
 
     if (data->source != NULL) {
         g_source_destroy(data->source);
-        g_vir_source_unref_safe(data->source);
+        vir_g_source_unref(data->source, NULL);
         data->source = NULL;
     }