diff options
| author | Guido Günther <agx@sigxcpu.org> | 2011-08-16 08:36:13 -0700 |
|---|---|---|
| committer | Daniel P. Berrange <berrange@redhat.com> | 2011-08-16 08:36:18 -0700 |
| commit | f3714e36625168fbd06b63e4b9979e7ea8258712 (patch) | |
| tree | f31b20d7cf3ae56839f50552fb179778faec9b76 /src | |
| parent | e155f7f656dd2bb5f939996be583e908afeec2a8 (diff) | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/virt-viewer-events.c | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c index 108f97d..87df739 100644 --- a/src/virt-viewer-events.c +++ b/src/virt-viewer-events.c @@ -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; } |
