summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabiano Fidêncio <fidencio@redhat.com>2015-07-22 03:16:37 +0200
committerFabiano Fidêncio <fidencio@redhat.com>2015-07-22 14:56:57 +0200
commitd28077ad08f46514f75ca13d9656635cc2111bd5 (patch)
treebc7984716edc28088f877cd59a6ebddbe02c3a5d
parent0a464aae9a764c404ea76fe2212d45e5b2d87d2f (diff)
downloadvirt-viewer-d28077ad08f46514f75ca13d9656635cc2111bd5.tar.gz
virt-viewer-d28077ad08f46514f75ca13d9656635cc2111bd5.tar.xz
virt-viewer-d28077ad08f46514f75ca13d9656635cc2111bd5.zip
events: remove timeout and handle from arrays
Otherwise, it will crash next time it goes find() Backtrace: (gdb) where #0 0x00007efcae715095 in g_io_create_watch () from /lib64/libglib-2.0.so.0 #1 0x00007efcae7150ef in g_io_add_watch_full () from /lib64/libglib-2.0.so.0 #2 0x00000000004275ba in virt_viewer_events_update_handle (watch=<optimized out>, events=1) at virt-viewer-events.c:158 #3 0x00007efcb1a62dce in virNetSocketUpdateIOCallback (sock=0x1e75c00, events=1) at rpc/virnetsocket.c:1981 #4 0x00007efcb1a50113 in virNetClientIOUpdateCallback (client=<optimized out>, enableCallback=<optimized out>) at rpc/virnetclient.c:1639 #5 0x00007efcb1a50f82 in virNetClientIO (thiscall=0x20e0170, client=0x1f2e060) at rpc/virnetclient.c:1793 #6 virNetClientSendInternal (client=client@entry=0x1f2e060, msg=msg@entry=0x20e0100, expectReply=expectReply@entry=false, nonBlock=nonBlock@entry=true) at rpc/virnetclient.c:1962 #7 0x00007efcb1a52413 in virNetClientSendNonBlock (client=0x1f2e060, msg=msg@entry=0x20e0100) at rpc/virnetclient.c:2036 #8 0x00007efcb1a5243d in virNetClientKeepAliveSendCB (opaque=<optimized out>, msg=0x20e0100) at rpc/virnetclient.c:293 #9 0x00007efcb1a5ba02 in virKeepAliveTimer (timer=<optimized out>, opaque=0x20d3d00) at rpc/virkeepalive.c:176 #10 0x00000000004272e9 in virt_viewer_events_dispatch_timeout (opaque=0x1e6cd30) at virt-viewer-events.c:233 #11 0x00007efcae7231b3 in g_timeout_dispatch () from /lib64/libglib-2.0.so.0 #12 0x00007efcae72279a in g_main_context_dispatch () from /lib64/libglib-2.0.so.0 #13 0x00007efcae722ae8 in g_main_context_iterate.isra.24 () from /lib64/libglib-2.0.so.0 #14 0x00007efcae722dba in g_main_loop_run () from /lib64/libglib-2.0.so.0 #15 0x00007efcb054a045 in gtk_main () from /lib64/libgtk-3.so.0 #16 0x0000000000410a9c in main (argc=1, argv=0x7ffde58a7978) at virt-viewer-main.c:124 Based on commit cff5f1c46f4b9661e112b85159fb58ae473a9a89 from libvirt-glib. Original author: Marc-André Lureau <marcandre.lureau@redhat.com> Related to: rhbz#1243228
-rw-r--r--src/virt-viewer-events.c80
1 files changed, 52 insertions, 28 deletions
diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
index daf128e..74828f5 100644
--- a/src/virt-viewer-events.c
+++ b/src/virt-viewer-events.c
@@ -50,8 +50,7 @@ struct virt_viewer_events_handle
};
static int nextwatch = 1;
-static unsigned int nhandles = 0;
-static struct virt_viewer_events_handle **handles = NULL;
+static GPtrArray *handles;
static gboolean
virt_viewer_events_dispatch_handle(GIOChannel *source G_GNUC_UNUSED,
@@ -91,9 +90,7 @@ int virt_viewer_events_add_handle(int fd,
g_mutex_lock(eventlock);
- handles = g_realloc(handles, sizeof(*handles)*(nhandles+1));
- data = g_malloc(sizeof(*data));
- memset(data, 0, sizeof(*data));
+ data = g_new0(struct virt_viewer_events_handle, 1);
if (events & VIR_EVENT_HANDLE_READABLE)
cond |= G_IO_IN;
@@ -120,7 +117,7 @@ int virt_viewer_events_add_handle(int fd,
virt_viewer_events_dispatch_handle,
data);
- handles[nhandles++] = data;
+ g_ptr_array_add(handles, data);
ret = data->watch;
@@ -130,12 +127,24 @@ int virt_viewer_events_add_handle(int fd,
}
static struct virt_viewer_events_handle *
-virt_viewer_events_find_handle(int watch)
+virt_viewer_events_find_handle(int watch, guint *idx)
{
- unsigned int i;
- for (i = 0 ; i < nhandles ; i++)
- if (handles[i]->watch == watch)
- return handles[i];
+ guint i;
+
+ for (i = 0 ; i < handles->len ; i++) {
+ struct virt_viewer_events_handle *h = g_ptr_array_index(handles, i);
+
+ if (h == NULL) {
+ g_warn_if_reached ();
+ continue;
+ }
+
+ if (h->watch == watch) {
+ if (idx != NULL)
+ *idx = i;
+ return h;
+ }
+ }
return NULL;
}
@@ -148,7 +157,7 @@ virt_viewer_events_update_handle(int watch,
g_mutex_lock(eventlock);
- data = virt_viewer_events_find_handle(watch);
+ data = virt_viewer_events_find_handle(watch, NULL);
if (!data) {
g_debug("Update for missing handle watch %d", watch);
@@ -198,7 +207,7 @@ virt_viewer_events_cleanup_handle(gpointer user_data)
if (data->ff)
(data->ff)(data->opaque);
- free(data);
+ g_ptr_array_remove_fast(handles, data);
return FALSE;
}
@@ -208,10 +217,11 @@ virt_viewer_events_remove_handle(int watch)
{
struct virt_viewer_events_handle *data;
int ret = -1;
+ guint idx;
g_mutex_lock(eventlock);
- data = virt_viewer_events_find_handle(watch);
+ data = virt_viewer_events_find_handle(watch, &idx);
if (!data) {
g_debug("Remove of missing watch %d", watch);
@@ -247,8 +257,7 @@ struct virt_viewer_events_timeout
static int nexttimer = 1;
-static unsigned int ntimeouts = 0;
-static struct virt_viewer_events_timeout **timeouts = NULL;
+static GPtrArray *timeouts;
static gboolean
virt_viewer_events_dispatch_timeout(void *opaque)
@@ -271,9 +280,7 @@ virt_viewer_events_add_timeout(int interval,
g_mutex_lock(eventlock);
- timeouts = g_realloc(timeouts, sizeof(*timeouts)*(ntimeouts+1));
- data = g_malloc(sizeof(*data));
- memset(data, 0, sizeof(*data));
+ data = g_new0(struct virt_viewer_events_timeout, 1);
data->timer = nexttimer++;
data->interval = interval;
@@ -285,7 +292,7 @@ virt_viewer_events_add_timeout(int interval,
virt_viewer_events_dispatch_timeout,
data);
- timeouts[ntimeouts++] = data;
+ g_ptr_array_add(timeouts, data);
g_debug("Add timeout %p %d %p %p %d", data, interval, cb, opaque, data->timer);
@@ -298,12 +305,26 @@ virt_viewer_events_add_timeout(int interval,
static struct virt_viewer_events_timeout *
-virt_viewer_events_find_timeout(int timer)
+virt_viewer_events_find_timeout(int timer, guint *idx)
{
- unsigned int i;
- for (i = 0 ; i < ntimeouts ; i++)
- if (timeouts[i]->timer == timer)
- return timeouts[i];
+ guint i;
+
+ g_return_val_if_fail(timeouts != NULL, NULL);
+
+ for (i = 0 ; i < timeouts->len ; i++) {
+ struct virt_viewer_events_timeout *t = g_ptr_array_index(timeouts, i);
+
+ if (t == NULL) {
+ g_warn_if_reached ();
+ continue;
+ }
+
+ if (t->timer == timer) {
+ if (idx != NULL)
+ *idx = i;
+ return t;
+ }
+ }
return NULL;
}
@@ -317,7 +338,7 @@ virt_viewer_events_update_timeout(int timer,
g_mutex_lock(eventlock);
- data = virt_viewer_events_find_timeout(timer);
+ data = virt_viewer_events_find_timeout(timer, NULL);
if (!data) {
g_debug("Update of missing timer %d", timer);
goto cleanup;
@@ -357,7 +378,7 @@ virt_viewer_events_cleanup_timeout(gpointer user_data)
if (data->ff)
(data->ff)(data->opaque);
- free(data);
+ g_ptr_array_remove_fast(timeouts, data);
return FALSE;
}
@@ -367,10 +388,11 @@ virt_viewer_events_remove_timeout(int timer)
{
struct virt_viewer_events_timeout *data;
int ret = -1;
+ guint idx;
g_mutex_lock(eventlock);
- data = virt_viewer_events_find_timeout(timer);
+ data = virt_viewer_events_find_timeout(timer, &idx);
if (!data) {
g_debug("Remove of missing timer %d", timer);
goto cleanup;
@@ -395,6 +417,8 @@ cleanup:
static gpointer event_register_once(gpointer data G_GNUC_UNUSED)
{
eventlock = g_mutex_new();
+ timeouts = g_ptr_array_new_with_free_func(g_free);
+ handles = g_ptr_array_new_with_free_func(g_free);
virEventRegisterImpl(virt_viewer_events_add_handle,
virt_viewer_events_update_handle,
virt_viewer_events_remove_handle,