Fix races that occur when a window id is destroyed and recreated very quickly. This...
authorDana Jansens <danakj@orodu.net>
Mon, 18 Feb 2008 21:44:41 +0000 (16:44 -0500)
committerDana Jansens <danakj@orodu.net>
Wed, 20 Feb 2008 05:42:46 +0000 (00:42 -0500)
Don't use windows that are destroyed when restacking other windows or when handling events on a window id.  It is possible for the same window id to appear in the window list multiple times if it is destroyed then created before the destroy fade-out completes.

xcompmgr.c

index 291624b..276d1bd 100644 (file)
@@ -100,6 +100,7 @@ typedef struct _win {
     unsigned int       opacity;
     wintype             windowType;
     unsigned long      damage_sequence;    /* sequence when damage was created */
     unsigned int       opacity;
     wintype             windowType;
     unsigned long      damage_sequence;    /* sequence when damage was created */
+    Bool                destroyed;
 
     Bool                need_configure;
     XConfigureEvent     queue_configure;
 
     Bool                need_configure;
     XConfigureEvent     queue_configure;
@@ -779,7 +780,7 @@ find_win (Display *dpy, Window id)
     win        *w;
 
     for (w = list; w; w = w->next)
     win        *w;
 
     for (w = list; w; w = w->next)
-       if (w->id == id)
+       if (w->id == id && !w->destroyed)
            return w;
     return 0;
 }
            return w;
     return 0;
 }
@@ -1513,7 +1514,7 @@ add_win (Display *dpy, Window id, Window prev)
     if (prev)
     {
        for (p = &list; *p; p = &(*p)->next)
     if (prev)
     {
        for (p = &list; *p; p = &(*p)->next)
-           if ((*p)->id == prev)
+           if ((*p)->id == prev && !(*p)->destroyed)
                break;
     }
     else
                break;
     }
     else
@@ -1553,6 +1554,7 @@ add_win (Display *dpy, Window id, Window prev)
     new->shadow_width = 0;
     new->shadow_height = 0;
     new->opacity = OPAQUE;
     new->shadow_width = 0;
     new->shadow_height = 0;
     new->opacity = OPAQUE;
+    new->destroyed = False;
     new->need_configure = False;
 
     new->borderClip = None;
     new->need_configure = False;
 
     new->borderClip = None;
@@ -1586,7 +1588,7 @@ restack_win (Display *dpy, win *w, Window new_above)
        /* rehook */
        for (prev = &list; *prev; prev = &(*prev)->next)
        {
        /* rehook */
        for (prev = &list; *prev; prev = &(*prev)->next)
        {
-           if ((*prev)->id == new_above)
+           if ((*prev)->id == new_above && !(*prev)->destroyed)
                break;
        }
        w->next = *prev;
                break;
        }
        w->next = *prev;
@@ -1693,7 +1695,7 @@ finish_destroy_win (Display *dpy, Window id)
     win        **prev, *w;
 
     for (prev = &list; (w = *prev); prev = &w->next)
     win        **prev, *w;
 
     for (prev = &list; (w = *prev); prev = &w->next)
-       if (w->id == id)
+       if (w->id == id && w->destroyed)
        {
             finish_unmap_win (dpy, w);
            *prev = w->next;
        {
             finish_unmap_win (dpy, w);
            *prev = w->next;
@@ -1733,6 +1735,8 @@ destroy_win (Display *dpy, Window id, Bool fade)
 {
     win *w = find_win (dpy, id);
 
 {
     win *w = find_win (dpy, id);
 
+    if (w) w->destroyed = True;
+
 #if HAS_NAME_WINDOW_PIXMAP
     if (w && w->pixmap && fade && winTypeFade[w->windowType])
        set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step,
 #if HAS_NAME_WINDOW_PIXMAP
     if (w && w->pixmap && fade && winTypeFade[w->windowType])
        set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step,