[PATCH v2] xwayland: Fix infinite loop on quick movement through menus

Kristian Hoegsberg hoegsberg at gmail.com
Fri Apr 27 12:33:09 PDT 2012


On Wed, Apr 25, 2012 at 10:00:42PM +0200, Tomasz Borowik wrote:
> On Wed, 25 Apr 2012 10:34:14 -0400
> Kristian Hoegsberg <hoegsberg at gmail.com> wrote:
> 
> > On Wed, Apr 25, 2012 at 03:06:57PM +0200, Tomasz Borowik wrote:
> > > From 3abf39489deb3eb048174630dc7d41908674408b Mon Sep 17 00:00:00 2001
> > > From: timon37 <timon37 at lavabit.com>
> > > Date: Wed, 25 Apr 2012 13:28:35 +0200
> > > Subject: [PATCH] Fix infinite loop in xwl_screen_post_damage
> > > 
> > > Happens when first two windows are damaged, then later one is damaged and
> > > the other is unrealized. It makes the damaged windows next point to itself.
> > 
> > Ah, yes, good catch.
> > 
> > The way we should fix this is that we just
> > 
> >     xorg_list_init(&xwl_window->damage_link);
> > 
> > in xwl_screen_post_damage() as we iterate list.  That way we can
> > unconditional call xorg_list_del(&xwl_window->link_damage); as we do
> > now.  If it's on the list, we take it out, if it's not on the list,
> > it's a no-op.
> > 
> 
> That was my initial thought, but that requires safe iterate (not
> exactly but I'm not sure if there is a method for cleaning the list
> in flight), and I came to the conclusion that damage happens way
> more often than unrealize so it's actually more efficient here.

Sure, but it's not acceptable to do a list search for something we can
determine in constant time.  What I did instead was:

diff --git a/hw/xfree86/xwayland/xwayland-window.c b/hw/xfree86/xwayland/xwaylan
index e58350f..09f93e0 100644
--- a/hw/xfree86/xwayland/xwayland-window.c
+++ b/hw/xfree86/xwayland/xwayland-window.c
@@ -248,7 +248,8 @@ xwl_unrealize_window(WindowPtr window)
        wl_buffer_destroy(xwl_window->buffer);
     wl_surface_destroy(xwl_window->surface);
     xorg_list_del(&xwl_window->link);
-    xorg_list_del(&xwl_window->link_damage);
+    if (!DamageEmpty(xwl_window->damage)
+       xorg_list_del(&xwl_window->link_damage);
     DamageUnregister(&window->drawable, xwl_window->damage);
     DamageDestroy(xwl_window->damage);
     free(xwl_window);

since the xwl_window is on the damage list iff the xwl_window->damage
is non-empty.

Kristian


More information about the wayland-devel mailing list