From nobody Fri Mar 29 14:03:19 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) client-ip=205.139.110.61; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1596039178; cv=none; d=zohomail.com; s=zohoarc; b=PCEIn0hn3z4O6WsgIidMBznmGgjiQr1G1tIuTtIrkl8DsBvwIZR1cVPHGz3prukSi+Z86mAQRJuAayzu2zUa2FBgtKt233Rkh7QXMmLCbXFH/flpsJRh8qVaJiFfi0Mb7qVW2YeX2I2rALjvSxz+MVu337NS55e2HKuwPq9qJiU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1596039178; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=FgdsZIomW3nixlZKLE0R0TjPzaDV03pLMeBITLGE+kM=; b=Z3DXIcIEEcGmU+uYMuAjgRpM/CQOCuWv8wZ/TYqeI8oi5eIOs7x3ZsSF2j1zgE/vBeae6BOr9sGaAqB8tn34gHjVCokBJ9aeQxWzyY3FKSPV/+K6zP0wdSyU7LEGsJm+K/wpLGqiXhRtpg0lVNWC5TbwksIqhrM7ABgFXa3rKW4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) by mx.zohomail.com with SMTPS id 1596039178533894.3689763978664; Wed, 29 Jul 2020 09:12:58 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-408-t0JPv0cOPbKXeJ8HYMsK2g-1; Wed, 29 Jul 2020 12:12:51 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id ED447800460; Wed, 29 Jul 2020 16:12:45 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CB09971909; Wed, 29 Jul 2020 16:12:45 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 9AF0E95A62; Wed, 29 Jul 2020 16:12:45 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 06TGAMlL006897 for ; Wed, 29 Jul 2020 12:10:22 -0400 Received: by smtp.corp.redhat.com (Postfix) id E98A35DA75; Wed, 29 Jul 2020 16:10:22 +0000 (UTC) Received: from domokun.gsslab.fab.redhat.com (unknown [10.33.8.110]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3368D5DA77; Wed, 29 Jul 2020 16:10:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1596039174; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=FgdsZIomW3nixlZKLE0R0TjPzaDV03pLMeBITLGE+kM=; b=Bmgrq0QbJ2tuI1qQ1fuurm6pgnBxbuABYSliP7WSAIwxVuNhJINJCYex7KueVl6GQ0vfHm 7xMbbLYyKZDK4Mt6mVRnOH9+tMk7dObybc4D/OUIGEyOe6ThTY7Km5jBgCHfDvqEbUtfG3 FUDzBkwKy+cGTusohpiIwpVpOwGkRTE= X-MC-Unique: t0JPv0cOPbKXeJ8HYMsK2g-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Subject: [libvirt PATCH 1/2] util: keep track of full GSource object not source ID number Date: Wed, 29 Jul 2020 17:10:16 +0100 Message-Id: <20200729161017.2714210-2-berrange@redhat.com> In-Reply-To: <20200729161017.2714210-1-berrange@redhat.com> References: <20200729161017.2714210-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) The source ID number is an alternative way to identify a source that has been added to a GMainContext. Internally when a source ID is given, glib will lookup the corresponding GSource and use that. The use of a source ID is racy in some cases though, because it is invalid to continue to use an ID number after the GSource has been removed. It is thus safer to use the GSource object directly and have full control over the ref counting and thus cleanup. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Michal Privoznik --- src/rpc/virnetclient.c | 27 +++++++------ src/util/vireventglib.c | 73 +++++++++++++++++++++++------------- src/util/vireventglibwatch.c | 19 ++++++---- src/util/vireventglibwatch.h | 13 ++++--- 4 files changed, 79 insertions(+), 53 deletions(-) diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c index 441f1502a6..6031d9ab5e 100644 --- a/src/rpc/virnetclient.c +++ b/src/rpc/virnetclient.c @@ -826,6 +826,7 @@ virNetClientIOEventTLS(int fd, static gboolean virNetClientTLSHandshake(virNetClientPtr client) { + g_autoptr(GSource) source =3D NULL; GIOCondition ev; int ret; =20 @@ -840,10 +841,10 @@ virNetClientTLSHandshake(virNetClientPtr client) else ev =3D G_IO_OUT; =20 - virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock), - ev, - client->eventCtx, - virNetClientIOEventTLS, client, NULL); + source =3D virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock), + ev, + client->eventCtx, + virNetClientIOEventTLS, client, NU= LL); =20 return TRUE; } @@ -882,6 +883,7 @@ int virNetClientSetTLSSession(virNetClientPtr client, int ret; char buf[1]; int len; + g_autoptr(GSource) source =3D NULL; =20 #ifndef WIN32 sigset_t oldmask, blockedsigs; @@ -934,10 +936,10 @@ int virNetClientSetTLSSession(virNetClientPtr client, * etc. If we make the grade, it will send us a '\1' byte. */ =20 - virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock), - G_IO_IN, - client->eventCtx, - virNetClientIOEventTLSConfirm, client, NULL= ); + source =3D virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock), + G_IO_IN, + client->eventCtx, + virNetClientIOEventTLSConfirm, cli= ent, NULL); =20 #ifndef WIN32 /* Block SIGWINCH from interrupting poll in curses programs */ @@ -1617,6 +1619,7 @@ static int virNetClientIOEventLoop(virNetClientPtr cl= ient, #endif /* !WIN32 */ int timeout =3D -1; virNetMessagePtr msg =3D NULL; + g_autoptr(GSource) source =3D NULL; GIOCondition ev =3D 0; struct virNetClientIOEventData data =3D { .client =3D client, @@ -1651,10 +1654,10 @@ static int virNetClientIOEventLoop(virNetClientPtr = client, if (client->nstreams) ev |=3D G_IO_IN; =20 - virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock), - ev, - client->eventCtx, - virNetClientIOEventFD, &data, NULL); + source =3D virEventGLibAddSocketWatch(virNetSocketGetFD(client->so= ck), + ev, + client->eventCtx, + virNetClientIOEventFD, &data, = NULL); =20 /* Release lock while poll'ing so other threads * can stuff themselves on the queue */ diff --git a/src/util/vireventglib.c b/src/util/vireventglib.c index 803332a6f8..6e334b3398 100644 --- a/src/util/vireventglib.c +++ b/src/util/vireventglib.c @@ -45,7 +45,7 @@ struct virEventGLibHandle int fd; int events; int removed; - guint source; + GSource *source; virEventHandleCallback cb; void *opaque; virFreeCallback ff; @@ -56,7 +56,7 @@ struct virEventGLibTimeout int timer; int interval; int removed; - guint source; + GSource *source; virEventTimeoutCallback cb; void *opaque; virFreeCallback ff; @@ -210,23 +210,25 @@ virEventGLibHandleUpdate(int watch, if (events =3D=3D data->events) goto cleanup; =20 - if (data->source !=3D 0) { - VIR_DEBUG("Removed old handle watch=3D%d", data->source); - g_source_remove(data->source); + if (data->source !=3D NULL) { + VIR_DEBUG("Removed old handle source=3D%p", data->source); + g_source_destroy(data->source); + g_source_unref(data->source); } =20 data->source =3D virEventGLibAddSocketWatch( data->fd, cond, NULL, virEventGLibHandleDispatch, data, NULL); =20 data->events =3D events; - VIR_DEBUG("Added new handle watch=3D%d", data->source); + VIR_DEBUG("Added new handle source=3D%p", data->source); } else { - if (data->source =3D=3D 0) + if (data->source =3D=3D NULL) goto cleanup; =20 - VIR_DEBUG("Removed old handle watch=3D%d", data->source); - g_source_remove(data->source); - data->source =3D 0; + VIR_DEBUG("Removed old handle source=3D%p", data->source); + g_source_destroy(data->source); + g_source_unref(data->source); + data->source =3D NULL; data->events =3D 0; } =20 @@ -272,9 +274,10 @@ virEventGLibHandleRemove(int watch) VIR_DEBUG("Remove handle data=3D%p watch=3D%d fd=3D%d", data, watch, data->fd); =20 - if (data->source !=3D 0) { - g_source_remove(data->source); - data->source =3D 0; + if (data->source !=3D NULL) { + g_source_destroy(data->source); + g_source_unref(data->source); + data->source =3D NULL; data->events =3D 0; } =20 @@ -309,6 +312,22 @@ virEventGLibTimeoutDispatch(void *opaque) return TRUE; } =20 + +static GSource * +virEventGLibTimeoutCreate(int interval, + struct virEventGLibTimeout *data) +{ + GSource *source =3D g_timeout_source_new(interval); + + g_source_set_callback(source, + virEventGLibTimeoutDispatch, + data, NULL); + g_source_attach(source, NULL); + + return source; +} + + static int virEventGLibTimeoutAdd(int interval, virEventTimeoutCallback cb, @@ -327,9 +346,7 @@ virEventGLibTimeoutAdd(int interval, data->opaque =3D opaque; data->ff =3D ff; if (interval >=3D 0) - data->source =3D g_timeout_add(interval, - virEventGLibTimeoutDispatch, - data); + data->source =3D virEventGLibTimeoutCreate(interval, data); =20 g_ptr_array_add(timeouts, data); =20 @@ -390,19 +407,20 @@ virEventGLibTimeoutUpdate(int timer, VIR_DEBUG("Update timeout data=3D%p timer=3D%d interval=3D%d ms", data= , timer, interval); =20 if (interval >=3D 0) { - if (data->source !=3D 0) - g_source_remove(data->source); + if (data->source !=3D NULL) { + g_source_destroy(data->source); + g_source_unref(data->source); + } =20 data->interval =3D interval; - data->source =3D g_timeout_add(data->interval, - virEventGLibTimeoutDispatch, - data); + data->source =3D virEventGLibTimeoutCreate(interval, data); } else { - if (data->source =3D=3D 0) + if (data->source =3D=3D NULL) goto cleanup; =20 - g_source_remove(data->source); - data->source =3D 0; + g_source_destroy(data->source); + g_source_unref(data->source); + data->source =3D NULL; } =20 cleanup: @@ -448,9 +466,10 @@ virEventGLibTimeoutRemove(int timer) VIR_DEBUG("Remove timeout data=3D%p timer=3D%d", data, timer); =20 - if (data->source !=3D 0) { - g_source_remove(data->source); - data->source =3D 0; + if (data->source !=3D NULL) { + g_source_destroy(data->source); + g_source_unref(data->source); + data->source =3D NULL; } =20 /* since the actual timeout deletion is done asynchronously, a timeout= Update call may diff --git a/src/util/vireventglibwatch.c b/src/util/vireventglibwatch.c index 178707f6b7..b7f3a8786a 100644 --- a/src/util/vireventglibwatch.c +++ b/src/util/vireventglibwatch.c @@ -233,17 +233,20 @@ GSource *virEventGLibCreateSocketWatch(int fd, #endif /* WIN32 */ =20 =20 -guint virEventGLibAddSocketWatch(int fd, - GIOCondition condition, - GMainContext *context, - virEventGLibSocketFunc func, - gpointer opaque, - GDestroyNotify notify) +GSource * +virEventGLibAddSocketWatch(int fd, + GIOCondition condition, + GMainContext *context, + virEventGLibSocketFunc func, + gpointer opaque, + GDestroyNotify notify) { - g_autoptr(GSource) source =3D NULL; + GSource *source =3D NULL; =20 source =3D virEventGLibCreateSocketWatch(fd, condition); g_source_set_callback(source, (GSourceFunc)func, opaque, notify); =20 - return g_source_attach(source, context); + g_source_attach(source, context); + + return source; } diff --git a/src/util/vireventglibwatch.h b/src/util/vireventglibwatch.h index 2f7e61cfba..f57be1f503 100644 --- a/src/util/vireventglibwatch.h +++ b/src/util/vireventglibwatch.h @@ -40,9 +40,10 @@ typedef gboolean (*virEventGLibSocketFunc)(int fd, GIOCondition condition, gpointer data); =20 -guint virEventGLibAddSocketWatch(int fd, - GIOCondition condition, - GMainContext *context, - virEventGLibSocketFunc func, - gpointer opaque, - GDestroyNotify notify); +GSource *virEventGLibAddSocketWatch(int fd, + GIOCondition condition, + GMainContext *context, + virEventGLibSocketFunc func, + gpointer opaque, + GDestroyNotify notify) + G_GNUC_WARN_UNUSED_RESULT; --=20 2.24.1 From nobody Fri Mar 29 14:03:19 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 207.211.31.120 as permitted sender) client-ip=207.211.31.120; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1596039181; cv=none; d=zohomail.com; s=zohoarc; b=DqYwKeoR0XFZzpGXXDEfk8K313GZM04/niUfg3/JobRFbWi0aMk0JH1qONypBDMKoUqDTM0r4ioCKYTi1V3Dnk9jdnsc5OmCfn7gSbE8Dss1Hr0m/Nwrs7oZDFA5KefB0cmPX/BtBxv3EpME/J1aO6RzvHjCoR3Rbc0IP4egNRg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1596039181; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=v89m6lf9/ZXErtyXBLBqKC57lS0ark4HS3bdjVpg+Ag=; b=P/Tb5/Y/gbaLJxxarfgu/C81HAqwOY6fCPM6gCkxmOojXmL8DAruQPPDYdnhICV68vce9MJ8RuFeeo7NiNaF7OPZcQjbX002ZV2TQAo4/T7KFQL+OruakN5jnohp61e4cPytfy+XgW+cibA9j+YQL89bURpUhvgUJcAJb+W9Yx0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) by mx.zohomail.com with SMTPS id 1596039181282283.01222569013566; Wed, 29 Jul 2020 09:13:01 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-217-zMIExt_wMN2s8aI4FlylMQ-1; Wed, 29 Jul 2020 12:12:56 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E1C2E80BCAC; Wed, 29 Jul 2020 16:12:48 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BCBEA8A161; Wed, 29 Jul 2020 16:12:48 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 8CE8295A71; Wed, 29 Jul 2020 16:12:48 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 06TGANPD006904 for ; Wed, 29 Jul 2020 12:10:23 -0400 Received: by smtp.corp.redhat.com (Postfix) id CEB975DA75; Wed, 29 Jul 2020 16:10:23 +0000 (UTC) Received: from domokun.gsslab.fab.redhat.com (unknown [10.33.8.110]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3BF4F5DA77; Wed, 29 Jul 2020 16:10:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1596039180; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=v89m6lf9/ZXErtyXBLBqKC57lS0ark4HS3bdjVpg+Ag=; b=MwamaaDwD3ECKMz2wXnpXfZtVjachkcSePTrxwYcwopBY6nJdGTFxbeYU5m3l1IZqcuykR FycUgX90jtDAtyfDoOQPOYgbd+s1iy28L/Rw0jzsxVILgpIHAZRjs75LXTpOX7nNth7i80 WJ+DQATMGenDULs1M1cu5ger9K86dHo= X-MC-Unique: zMIExt_wMN2s8aI4FlylMQ-1 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Subject: [libvirt PATCH 2/2] util: avoid crash due to race in glib event loop code Date: Wed, 29 Jul 2020 17:10:17 +0100 Message-Id: <20200729161017.2714210-3-berrange@redhat.com> In-Reply-To: <20200729161017.2714210-1-berrange@redhat.com> References: <20200729161017.2714210-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) There is a fairly long standing race condition bug in glib which can hit if you call g_source_destroy or g_source_unref from a non-main thread: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1358 Unfortunately it is really common for libvirt to call g_source_destroy from a non-main thread. This glib bug is the cause of non-determinstic crashes in eventtest, and probably in libvirtd too. To work around the problem we need to ensure that we never release the last reference on a GSource from a non-main thread. The previous patch replaced our use of g_source_destroy with a pair of g_source_remove and g_source_unref. We can now delay the g_source_unref call by using a idle callback to invoke it from the main thread which avoids the race condition. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: Michal Privoznik --- src/util/vireventglib.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/util/vireventglib.c b/src/util/vireventglib.c index 6e334b3398..7e61b096ed 100644 --- a/src/util/vireventglib.c +++ b/src/util/vireventglib.c @@ -185,6 +185,24 @@ virEventGLibHandleFind(int watch) return NULL; } =20 +/* + * If the last refernce to a GSource is released in a non-main + * thread we're exposed to a race condition that causes a + * crash: + * https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1358 + * Thus we're using an idle func to release our ref + */ +static gboolean +virEventGLibSourceUnrefIdle(gpointer data) +{ + GSource *src =3D data; + + g_source_unref(src); + + return FALSE; +} + + static void virEventGLibHandleUpdate(int watch, int events) @@ -213,7 +231,7 @@ virEventGLibHandleUpdate(int watch, if (data->source !=3D NULL) { VIR_DEBUG("Removed old handle source=3D%p", data->source); g_source_destroy(data->source); - g_source_unref(data->source); + g_idle_add(virEventGLibSourceUnrefIdle, data->source); } =20 data->source =3D virEventGLibAddSocketWatch( @@ -227,7 +245,7 @@ virEventGLibHandleUpdate(int watch, =20 VIR_DEBUG("Removed old handle source=3D%p", data->source); g_source_destroy(data->source); - g_source_unref(data->source); + g_idle_add(virEventGLibSourceUnrefIdle, data->source); data->source =3D NULL; data->events =3D 0; } @@ -276,7 +294,7 @@ virEventGLibHandleRemove(int watch) =20 if (data->source !=3D NULL) { g_source_destroy(data->source); - g_source_unref(data->source); + g_idle_add(virEventGLibSourceUnrefIdle, data->source); data->source =3D NULL; data->events =3D 0; } @@ -409,7 +427,7 @@ virEventGLibTimeoutUpdate(int timer, if (interval >=3D 0) { if (data->source !=3D NULL) { g_source_destroy(data->source); - g_source_unref(data->source); + g_idle_add(virEventGLibSourceUnrefIdle, data->source); } =20 data->interval =3D interval; @@ -419,7 +437,7 @@ virEventGLibTimeoutUpdate(int timer, goto cleanup; =20 g_source_destroy(data->source); - g_source_unref(data->source); + g_idle_add(virEventGLibSourceUnrefIdle, data->source); data->source =3D NULL; } =20 @@ -468,7 +486,7 @@ virEventGLibTimeoutRemove(int timer) =20 if (data->source !=3D NULL) { g_source_destroy(data->source); - g_source_unref(data->source); + g_idle_add(virEventGLibSourceUnrefIdle, data->source); data->source =3D NULL; } =20 --=20 2.24.1