On Fri, Mar 11, 2011 at 7:32 PM, Iskren Chernev <iskren.cher...@gmail.com> wrote: > Hello, > I found a bug and fixed it with the patch :) > to reproduce:
Hi, I wasn't able to reproduce it immediately, but I know that there's a crasher in there somewhere. I think the real fix is the patch I've attached, could you give it a try and see if it fixes it for you? thanks, Kristian > run compositor on top of x11 > repeat > run flower > drag & drop it a little > move the pointer in and out of the compositor/flower > Ctrl+C the flower client > it would break eventually > problem: > I found that the linked list surface->destroy_listener_list got corrupted at > some point (it was not circular any more, strange next/prev etc), which > causes the crash. > solution: > The problem was in wl_list_remove -- when you erase an element, you don't > mark it as 'erased', by setting prev/next to NULL for example. Then if you > erase it again the list becomes corrupt. I nullified the prev/next and check > in the begining of wl_list_remove for not-in-list elements and just ignore > them. That seems to fix it. > Regards, > Iskren > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel > >
From 249c42a153e94e12e6734465e94d310dcf2421da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= <k...@bitplanet.net> Date: Sat, 12 Mar 2011 21:26:21 -0500 Subject: [PATCH] Fix double remove from surface destroy_listener_list We remove the listener when a device loses its pointer focus, but doesn't insert it in another destroy_listener list if surface is NULL. Tracked down by Iskren Chernev. --- wayland/wayland-server.c | 24 +++++++++++++----------- 1 files changed, 13 insertions(+), 11 deletions(-) diff --git a/wayland/wayland-server.c b/wayland/wayland-server.c index dece0d1..c505e32 100644 --- a/wayland/wayland-server.c +++ b/wayland/wayland-server.c @@ -356,19 +356,21 @@ wl_input_device_set_pointer_focus(struct wl_input_device *device, &device->object, WL_INPUT_DEVICE_POINTER_FOCUS, time, NULL, 0, 0, 0, 0); - if (surface) + if (device->pointer_focus) + wl_list_remove(&device->pointer_focus_listener.link); + + if (surface) { wl_client_post_event(surface->client, &device->object, WL_INPUT_DEVICE_POINTER_FOCUS, time, surface, x, y, sx, sy); + wl_list_insert(surface->destroy_listener_list.prev, + &device->pointer_focus_listener.link); + } device->pointer_focus = surface; device->pointer_focus_time = time; - wl_list_remove(&device->pointer_focus_listener.link); - if (surface) - wl_list_insert(surface->destroy_listener_list.prev, - &device->pointer_focus_listener.link); } WL_EXPORT void @@ -385,20 +387,20 @@ wl_input_device_set_keyboard_focus(struct wl_input_device *device, &device->object, WL_INPUT_DEVICE_KEYBOARD_FOCUS, time, NULL, &device->keys); + if (device->keyboard_focus) + wl_list_remove(&device->keyboard_focus_listener.link); - if (surface) + if (surface) { wl_client_post_event(surface->client, &device->object, WL_INPUT_DEVICE_KEYBOARD_FOCUS, time, surface, &device->keys); + wl_list_insert(surface->destroy_listener_list.prev, + &device->keyboard_focus_listener.link); + } device->keyboard_focus = surface; device->keyboard_focus_time = time; - - wl_list_remove(&device->keyboard_focus_listener.link); - if (surface) - wl_list_insert(surface->destroy_listener_list.prev, - &device->keyboard_focus_listener.link); } WL_EXPORT void -- 1.7.4.1
_______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel