Codebase list virt-viewer / 9e79afb
ff callbacks must be invoked from a clean stack. Fixes a hang when connecting to an unknown host or wrong port. Guido Günther 12 years ago
2 changed file(s) with 97 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 From: =?UTF-8?q?Guido=20G=C3=BCnther?= <agx@sigxcpu.org>
1 Date: Tue, 16 Aug 2011 08:36:13 -0700
2 Subject: ff callbacks must be invoked from a clean stack
3
4 If 'ff' callbacks are invoked directly from the remove
5 callback they will likely deadlock in libvirt. They must
6 be invoked from a clean stack, so switch to using a
7 glib idle callback.
8 ---
9 src/virt-viewer-events.c | 47 ++++++++++++++++++++++++++++++++++++++-------
10 1 files changed, 39 insertions(+), 8 deletions(-)
11
12 diff --git a/src/virt-viewer-events.c b/src/virt-viewer-events.c
13 index 108f97d..87df739 100644
14 --- a/src/virt-viewer-events.c
15 +++ b/src/virt-viewer-events.c
16 @@ -160,6 +160,23 @@ virt_viewer_events_update_handle(int watch,
17 }
18 }
19
20 +
21 +static gboolean
22 +virt_viewer_events_cleanup_handle(gpointer user_data)
23 +{
24 + struct virt_viewer_events_handle *data = user_data;
25 +
26 + DEBUG_LOG("Cleanup of handle %p", data);
27 + g_return_val_if_fail(data != NULL, FALSE);
28 +
29 + if (data->ff)
30 + (data->ff)(data->opaque);
31 +
32 + free(data);
33 + return FALSE;
34 +}
35 +
36 +
37 static int
38 virt_viewer_events_remove_handle(int watch)
39 {
40 @@ -172,13 +189,14 @@ virt_viewer_events_remove_handle(int watch)
41
42 DEBUG_LOG("Remove handle %d %d", watch, data->fd);
43
44 + if (!data->source)
45 + return -1;
46 +
47 g_source_remove(data->source);
48 data->source = 0;
49 data->events = 0;
50 - if (data->ff)
51 - (data->ff)(data->opaque);
52 - free(data);
53
54 + g_idle_add(virt_viewer_events_cleanup_handle, data);
55 return 0;
56 }
57
58 @@ -279,6 +297,23 @@ virt_viewer_events_update_timeout(int timer,
59 }
60 }
61
62 +
63 +static gboolean
64 +virt_viewer_events_cleanup_timeout(gpointer user_data)
65 +{
66 + struct virt_viewer_events_timeout *data = user_data;
67 +
68 + DEBUG_LOG("Cleanup of timeout %p", data);
69 + g_return_val_if_fail(data != NULL, FALSE);
70 +
71 + if (data->ff)
72 + (data->ff)(data->opaque);
73 +
74 + free(data);
75 + return FALSE;
76 +}
77 +
78 +
79 static int
80 virt_viewer_events_remove_timeout(int timer)
81 {
82 @@ -297,11 +332,7 @@ virt_viewer_events_remove_timeout(int timer)
83 g_source_remove(data->source);
84 data->source = 0;
85
86 - if (data->ff)
87 - (data->ff)(data->opaque);
88 -
89 - free(data);
90 -
91 + g_idle_add(virt_viewer_events_cleanup_timeout, data);
92 return 0;
93 }
94
95 --
00 0001-Really-fix-using-alternate-ssh-ports.patch
1 0002-ff-callbacks-must-be-invoked-from-a-clean-stack.patch