On Mon, Jun 25, 2012 at 11:03:16AM +0100, Daniel P. Berrange wrote: > On Wed, Jun 20, 2012 at 12:29:51PM +0200, Christophe Fergeau wrote: > > The deletion of libvirt timeouts/watches is done in 2 steps: > > - the first step is synchronous and unregisters the timeout/watch > > from glib mainloop > > - the second step is asynchronous and triggered from the first step. > > It releases the memory used for bookkeeping for the timeout/watch > > being deleted > > > > This is done this way to avoid some possible deadlocks when > > reentering the sync callback while freeing the memory associated > > with the timeout/watch. > > > > However, it's possible to call gvir_event_update_handle after > > gvir_event_remove_handle but before _event_handle_remove does > > the final cleanup. When this happen, _update_handle will reregister > > the handle with glib mainloop, and bad things will happen when > > a glib callback is triggered for this event after _event_handle_remove > > has freed the memory associated with this handle watch. > > That's clearly possible, but it is also illegal use of the events > API by some client code, since the timer/watch id is not valid > after calling remove(). Do you actually see this occurring in > real life ? Yes, I've seen this with gnome-boxes when starting a VM and then letting it run in the background, see the cover letter for a few more details I've just added if (h->removed) G_BREAKPOINT; to gvir_event_timeout_find to catch a backtrace when this happens: (gdb) bt #0 gvir_event_handle_find (watch=1) at libvirt-glib-event.c:202 #1 0x00007ffff6670b78 in gvir_event_handle_update (watch=1, events=1) at libvirt-glib-event.c:218 #2 0x00007ffff5f400e9 in virEventUpdateHandle (watch=1, events=1) at util/event.c:70 #3 0x00007ffff60823f1 in virNetSocketUpdateIOCallback (sock=0x7fffdc001fe0, events=1) at rpc/virnetsocket.c:1384 #4 0x00007ffff606e74e in virNetClientIOUpdateCallback (client=0x7fffdc001e20, enableCallback=true) at rpc/virnetclient.c:1454 #5 0x00007ffff606ecec in virNetClientIncomingEvent (sock=0x7fffdc001fe0, events=2, opaque=0x7fffdc001e20) at rpc/virnetclient.c:1659 #6 0x00007ffff608213c in virNetSocketEventHandle (watch=1, fd=26, events=2, opaque=0x7fffdc001fe0) at rpc/virnetsocket.c:1314 #7 0x00007ffff66708cd in gvir_event_handle_dispatch (source=0x7fffdc001f60, condition=G_IO_OUT, opaque=0x7fffdc001930) at libvirt-glib-event.c:136 #8 0x00007ffff1e20cb4 in g_io_unix_dispatch (source=0x7fffdc0017d0, callback=0x7ffff66707f8 <gvir_event_handle_dispatch>, user_data=0x7fffdc001930) at giounix.c:166 #9 0x00007ffff1dd1f15 in g_main_dispatch (context=0x6fea30) at gmain.c:2539 #10 0x00007ffff1dd2bda in g_main_context_dispatch (context=0x6fea30) at gmain.c:3075 #11 0x00007ffff1dd2dbd in g_main_context_iterate (context=0x6fea30, block=1, dispatch=1, self=0x728780) at gmain.c:3146 #12 0x00007ffff1dd2e81 in g_main_context_iteration (context=0x6fea30, may_block=1) at gmain.c:3207 #13 0x00007ffff25dbe7c in g_application_run (application=0x709890, argc=0, argv=0x0) at gapplication.c:1607 #14 0x000000000041dec8 in boxes_app_run (self=0x1525010) at app.c:1187 #15 0x00000000004506f4 in _vala_main (args=0x7fffffffd738, args_length1=1) at main.c:729 #16 0x000000000045075e in main (argc=1, argv=0x7fffffffd738) at main.c:740 It happens at more or less random times, so I'm not sure if I'll be able to catch a backtrace when the watch is removed. Christophe
Attachment:
pgpRskrxJEXoQ.pgp
Description: PGP signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list