The reason is that the vnc_display_open* functions register an idle callback to launch the coroutine, but if vnc_display_close is called before the idle loop has had a moment to run, this idle callback remains. The coroutine later runs - in my case, after the plugin I'm writing has been unmapped from memory, with unhappy consequences.
The attached patch fixes this by remembering the callback ID and unregistering it if necessary.
Rich. -- Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/ Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 03798903
diff -r 95f570fc49e1 src/vncdisplay.c --- a/src/vncdisplay.c Wed Jan 09 23:54:24 2008 -0500 +++ b/src/vncdisplay.c Thu Jan 10 17:29:22 2008 +0000 @@ -40,6 +40,8 @@ struct _VncDisplayPrivate struct gvnc_framebuffer fb; struct coroutine coroutine; struct gvnc *gvnc; + + guint open_id; gboolean in_pointer_grab; gboolean in_keyboard_grab; @@ -889,6 +891,8 @@ static gboolean do_vnc_display_open(gpoi return FALSE; } + obj->priv->open_id = 0; + co = &obj->priv->coroutine; co->stack_size = 16 << 20; @@ -911,7 +915,7 @@ gboolean vnc_display_open_fd(VncDisplay obj->priv->port = NULL; g_object_ref(G_OBJECT(obj)); /* Unref'd when co-routine exits */ - g_idle_add(do_vnc_display_open, obj); + obj->priv->open_id = g_idle_add(do_vnc_display_open, obj); return TRUE; } @@ -933,7 +937,7 @@ gboolean vnc_display_open_host(VncDispla } g_object_ref(G_OBJECT(obj)); /* Unref'd when co-routine exits */ - g_idle_add(do_vnc_display_open, obj); + obj->priv->open_id = g_idle_add(do_vnc_display_open, obj); return TRUE; } @@ -946,6 +950,11 @@ gboolean vnc_display_is_open(VncDisplay void vnc_display_close(VncDisplay *obj) { + if (obj->priv->open_id) { + g_source_remove (obj->priv->open_id); + obj->priv->open_id = 0; + } + if (obj->priv->gvnc == NULL) return;
Attachment:
smime.p7s
Description: S/MIME Cryptographic Signature