ff callbacks must be invoked from a clean stack

If 'ff' callbacks are invoked directly from the remove
callback they will likely deadlock in libvirt. They must
be invoked from a clean stack, so switch to using a
glib idle callback.
This commit is contained in:
Guido Günther 2011-08-16 08:36:13 -07:00 committed by Daniel P. Berrange
parent e155f7f656
commit f3714e3662

View File

@ -160,6 +160,23 @@ virt_viewer_events_update_handle(int watch,
}
}
static gboolean
virt_viewer_events_cleanup_handle(gpointer user_data)
{
struct virt_viewer_events_handle *data = user_data;
DEBUG_LOG("Cleanup of handle %p", data);
g_return_val_if_fail(data != NULL, FALSE);
if (data->ff)
(data->ff)(data->opaque);
free(data);
return FALSE;
}
static int
virt_viewer_events_remove_handle(int watch)
{
@ -172,13 +189,14 @@ virt_viewer_events_remove_handle(int watch)
DEBUG_LOG("Remove handle %d %d", watch, data->fd);
if (!data->source)
return -1;
g_source_remove(data->source);
data->source = 0;
data->events = 0;
if (data->ff)
(data->ff)(data->opaque);
free(data);
g_idle_add(virt_viewer_events_cleanup_handle, data);
return 0;
}
@ -279,6 +297,23 @@ virt_viewer_events_update_timeout(int timer,
}
}
static gboolean
virt_viewer_events_cleanup_timeout(gpointer user_data)
{
struct virt_viewer_events_timeout *data = user_data;
DEBUG_LOG("Cleanup of timeout %p", data);
g_return_val_if_fail(data != NULL, FALSE);
if (data->ff)
(data->ff)(data->opaque);
free(data);
return FALSE;
}
static int
virt_viewer_events_remove_timeout(int timer)
{
@ -297,11 +332,7 @@ virt_viewer_events_remove_timeout(int timer)
g_source_remove(data->source);
data->source = 0;
if (data->ff)
(data->ff)(data->opaque);
free(data);
g_idle_add(virt_viewer_events_cleanup_timeout, data);
return 0;
}