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>
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 ],
)
+++ /dev/null
-#
-# 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:
# util/glibcompat.h
vir_g_canonicalize_filename;
vir_g_fsync;
+vir_g_source_unref;
vir_g_strdup_printf;
vir_g_strdup_vprintf;
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 = []
{
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;
}
}
{
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;
}
}
*
* 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;
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
#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);
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(
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;
}
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;
}
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;
goto cleanup;
g_source_destroy(data->source);
- g_vir_source_unref_safe(data->source);
+ vir_g_source_unref(data->source, NULL);
data->source = NULL;
}
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;
}