mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 19:32:19 +00:00
util: avoid glib event loop workaround where possible
I previously did a workaround for a glib event loop race that causes crashes: commit 0db4743645b7a0611a3c0687f834205c9956f7fc Author: Daniel P. Berrangé <berrange@redhat.com> Date: Tue Jul 28 16:52:47 2020 +0100 util: avoid crash due to race in glib event loop code it turns out that the workaround has a significant performance penalty on I/O intensive workloads. We thus need to avoid the workaround if we know we have a new enough glib to avoid the race condition. Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> Tested-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
829142699e
commit
6d69afe451
@ -189,9 +189,21 @@ virEventGLibHandleFind(int watch)
|
|||||||
* If the last reference to a GSource is released in a non-main
|
* If the last reference to a GSource is released in a non-main
|
||||||
* thread we're exposed to a race condition that causes a
|
* thread we're exposed to a race condition that causes a
|
||||||
* crash:
|
* crash:
|
||||||
* https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1358
|
*
|
||||||
* Thus we're using an idle func to release our ref
|
* https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1358
|
||||||
|
*
|
||||||
|
* Thus we're using an idle func to release our ref...
|
||||||
|
*
|
||||||
|
* ...but this imposes a significant performance penalty on
|
||||||
|
* I/O intensive workloads which are sensitive to the iterations
|
||||||
|
* of the event loop, so avoid the workaround if we know we have
|
||||||
|
* new enough glib.
|
||||||
*/
|
*/
|
||||||
|
#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)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
virEventGLibSourceUnrefIdle(gpointer data)
|
virEventGLibSourceUnrefIdle(gpointer data)
|
||||||
{
|
{
|
||||||
@ -201,6 +213,7 @@ virEventGLibSourceUnrefIdle(gpointer data)
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -231,7 +244,7 @@ virEventGLibHandleUpdate(int watch,
|
|||||||
if (data->source != NULL) {
|
if (data->source != NULL) {
|
||||||
VIR_DEBUG("Removed old handle source=%p", data->source);
|
VIR_DEBUG("Removed old handle source=%p", data->source);
|
||||||
g_source_destroy(data->source);
|
g_source_destroy(data->source);
|
||||||
g_idle_add(virEventGLibSourceUnrefIdle, data->source);
|
g_vir_source_unref_safe(data->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->source = virEventGLibAddSocketWatch(
|
data->source = virEventGLibAddSocketWatch(
|
||||||
@ -245,7 +258,7 @@ virEventGLibHandleUpdate(int watch,
|
|||||||
|
|
||||||
VIR_DEBUG("Removed old handle source=%p", data->source);
|
VIR_DEBUG("Removed old handle source=%p", data->source);
|
||||||
g_source_destroy(data->source);
|
g_source_destroy(data->source);
|
||||||
g_idle_add(virEventGLibSourceUnrefIdle, data->source);
|
g_vir_source_unref_safe(data->source);
|
||||||
data->source = NULL;
|
data->source = NULL;
|
||||||
data->events = 0;
|
data->events = 0;
|
||||||
}
|
}
|
||||||
@ -294,7 +307,7 @@ virEventGLibHandleRemove(int watch)
|
|||||||
|
|
||||||
if (data->source != NULL) {
|
if (data->source != NULL) {
|
||||||
g_source_destroy(data->source);
|
g_source_destroy(data->source);
|
||||||
g_idle_add(virEventGLibSourceUnrefIdle, data->source);
|
g_vir_source_unref_safe(data->source);
|
||||||
data->source = NULL;
|
data->source = NULL;
|
||||||
data->events = 0;
|
data->events = 0;
|
||||||
}
|
}
|
||||||
@ -427,7 +440,7 @@ virEventGLibTimeoutUpdate(int timer,
|
|||||||
if (interval >= 0) {
|
if (interval >= 0) {
|
||||||
if (data->source != NULL) {
|
if (data->source != NULL) {
|
||||||
g_source_destroy(data->source);
|
g_source_destroy(data->source);
|
||||||
g_idle_add(virEventGLibSourceUnrefIdle, data->source);
|
g_vir_source_unref_safe(data->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->interval = interval;
|
data->interval = interval;
|
||||||
@ -437,7 +450,7 @@ virEventGLibTimeoutUpdate(int timer,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
g_source_destroy(data->source);
|
g_source_destroy(data->source);
|
||||||
g_idle_add(virEventGLibSourceUnrefIdle, data->source);
|
g_vir_source_unref_safe(data->source);
|
||||||
data->source = NULL;
|
data->source = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,7 +499,7 @@ virEventGLibTimeoutRemove(int timer)
|
|||||||
|
|
||||||
if (data->source != NULL) {
|
if (data->source != NULL) {
|
||||||
g_source_destroy(data->source);
|
g_source_destroy(data->source);
|
||||||
g_idle_add(virEventGLibSourceUnrefIdle, data->source);
|
g_vir_source_unref_safe(data->source);
|
||||||
data->source = NULL;
|
data->source = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user