The aim is to move parts of vir_event_thread_finalize() that MAY block into a separate function, so that unrefing the a virEventThread no longer blocks (or require releasing and subsequent re-acquiring of a mutex). Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/vireventthread.c | 22 ++++++++++++++++++++++ src/util/vireventthread.h | 2 ++ 3 files changed, 25 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c35366c9e1..14c220ee80 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2284,6 +2284,7 @@ virEventGLibRunOnce; # util/vireventthread.h virEventThreadGetContext; virEventThreadNew; +virEventThreadStop; # util/virfcp.h diff --git a/src/util/vireventthread.c b/src/util/vireventthread.c index 20d52b9efb..131f53820f 100644 --- a/src/util/vireventthread.c +++ b/src/util/vireventthread.c @@ -188,6 +188,28 @@ virEventThreadNew(const char *name) } +/** + * virEventThreadStop: + * @evt: event thread + * + * May block until all events are processed. Typical use case is: + * + * virEventThread *evt = virEventThreadNew("name"); + * ... + * virEventThreadStop(evt); + * g_object_unref(evt); + */ +void +virEventThreadStop(virEventThread *evt) +{ + if (evt->thread) { + g_main_loop_quit(evt->loop); + g_thread_join(evt->thread); + evt->thread = NULL; + } +} + + GMainContext * virEventThreadGetContext(virEventThread *evt) { diff --git a/src/util/vireventthread.h b/src/util/vireventthread.h index 5826c25cf4..78d842b894 100644 --- a/src/util/vireventthread.h +++ b/src/util/vireventthread.h @@ -28,4 +28,6 @@ G_DECLARE_FINAL_TYPE(virEventThread, vir_event_thread, VIR, EVENT_THREAD, GObjec virEventThread *virEventThreadNew(const char *name); +void virEventThreadStop(virEventThread *evt); + GMainContext *virEventThreadGetContext(virEventThread *evt); -- 2.44.2