summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabiano FidĂȘncio <fidencio@redhat.com>2015-07-22 03:44:15 +0200
committerFabiano FidĂȘncio <fidencio@redhat.com>2015-07-22 14:56:57 +0200
commit3874a3015d721946d843bb4f141d3805b5fa748d (patch)
treed05a89c6ecf0c8eb603bc0dd747f900f7bb7d6b1
parent31fa350266e5c85c4129cf23405844115a3aae26 (diff)
downloadvirt-viewer-3874a3015d721946d843bb4f141d3805b5fa748d.tar.gz
virt-viewer-3874a3015d721946d843bb4f141d3805b5fa748d.tar.xz
virt-viewer-3874a3015d721946d843bb4f141d3805b5fa748d.zip
events: protect 'handles' and 'timeouts' against concurrent accesses
Timeout and watch deletion is done from an idle callback. However, we cannot assume that all libvirt event calls (the callbacks passed to virEventRegisterImpl) will be done from the mainloop thread. It's thus possible that a libvirt event call will run a thread while one of the idle deletion callbacks runs. Given that the 'handles' and 'timeouts' arrays are shared among all threads, we need to make sure we hold the 'eventlock' mutex before modifying them. Based on commit 924178f6b35735458b37d30303fe7bc753dde0b1 from libvirt-glib. Original author: Christophe Fergeau <cfergeau@redhat.com> Related to: rhbz#1243228
-rw-r--r--src/virt-viewer-events.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
index 3d05502..65db605 100644
--- a/src/virt-viewer-events.c
+++ b/src/virt-viewer-events.c
@@ -203,10 +203,15 @@ virt_viewer_events_cleanup_handle(gpointer user_data)
g_debug("Cleanup of handle %p", data);
g_return_val_if_fail(data != NULL, FALSE);
+ g_mutex_lock(eventlock);
+
if (data->ff)
(data->ff)(data->opaque);
g_ptr_array_remove_fast(handles, data);
+
+ g_mutex_unlock(eventlock);
+
return FALSE;
}
@@ -371,10 +376,15 @@ virt_viewer_events_cleanup_timeout(gpointer user_data)
g_debug("Cleanup of timeout %p", data);
g_return_val_if_fail(data != NULL, FALSE);
+ g_mutex_lock(eventlock);
+
if (data->ff)
(data->ff)(data->opaque);
g_ptr_array_remove_fast(timeouts, data);
+
+ g_mutex_unlock(eventlock);
+
return FALSE;
}