commit 516f9e7

Michael Forney  ·  2013-12-04 04:49:49 +0000 UTC
parent ae98130
Move window cleanup to swc_window_finalize

This avoids the case where the window implementation surface destroy
listener is called before the window's destroy listener, resulting in
accesses to freed memory.

It also matches better with the initialize/finalize style.
5 files changed,  +13, -23
+1, -0
1@@ -183,6 +183,7 @@ static void destroy_shell_surface(struct wl_resource * resource)
2     struct swc_shell_surface * shell_surface
3         = wl_resource_get_user_data(resource);
4 
5+    swc_window_finalize(&shell_surface->window.base);
6     free(shell_surface);
7 }
8 
+1, -0
1@@ -355,6 +355,7 @@ struct swc_surface * swc_surface_new(struct wl_client * client,
2     surface->geometry.width = 0;
3     surface->geometry.height = 0;
4     surface->pending.commit = 0;
5+    surface->window = NULL;
6     surface->class = NULL;
7     surface->class_state = NULL;
8 
+1, -0
1@@ -112,6 +112,7 @@ struct swc_surface
2         int32_t x, y;
3     } pending;
4 
5+    struct swc_window * window;
6     const struct swc_surface_class * class;
7     void * class_state;
8 
+9, -21
 1@@ -44,7 +44,7 @@ static void handle_window_enter(struct wl_listener * listener, void * data)
 2     if (event->type != SWC_INPUT_FOCUS_EVENT_CHANGED)
 3         return;
 4 
 5-    if (!event_data->new || !(window = swc_window_get(event_data->new)))
 6+    if (!event_data->new || !(window = event_data->new->window))
 7         return;
 8 
 9     swc_send_event(&window->event_signal, SWC_WINDOW_ENTERED, NULL);
10@@ -96,29 +96,20 @@ void swc_window_set_border(struct swc_window * window,
11     swc_compositor_surface_set_border_width(surface, border_width);
12 }
13 
14-static void handle_surface_destroy(struct wl_listener * listener, void * data)
15-{
16-    struct swc_window * window = &CONTAINER_OF
17-        (listener, struct swc_window_internal, surface_destroy_listener)->base;
18-
19-    swc_send_event(&window->event_signal, SWC_WINDOW_DESTROYED, NULL);
20-    swc_surface_set_class(INTERNAL(window)->surface, NULL);
21-}
22-
23 bool swc_window_initialize(struct swc_window * window,
24                            const struct swc_window_impl * impl,
25                            struct swc_surface * surface)
26 {
27+    DEBUG("Initializing window, %p\n", window);
28+
29     window->title = NULL;
30     window->class = NULL;
31     window->state = SWC_WINDOW_STATE_WITHDRAWN;
32     wl_signal_init(&window->event_signal);
33     INTERNAL(window)->surface = surface;
34-    INTERNAL(window)->surface_destroy_listener.notify = &handle_surface_destroy;
35     INTERNAL(window)->impl = impl;
36 
37-    wl_resource_add_destroy_listener
38-        (surface->resource, &INTERNAL(window)->surface_destroy_listener);
39+    surface->window = window;
40     swc_surface_set_class(surface, &swc.compositor->compositor_class);
41 
42     swc.manager->new_window(window);
43@@ -126,16 +117,13 @@ bool swc_window_initialize(struct swc_window * window,
44     return true;
45 }
46 
47-struct swc_window * swc_window_get(struct swc_surface * surface)
48+void swc_window_finalize(struct swc_window * window)
49 {
50-    struct wl_listener * listener;
51-
52-    listener = wl_resource_get_destroy_listener(surface->resource,
53-                                                &handle_surface_destroy);
54+    DEBUG("Finalizing window, %p\n", window);
55 
56-    return listener ? &CONTAINER_OF(listener, struct swc_window_internal,
57-                                    surface_destroy_listener)->base
58-                    : NULL;
59+    swc_send_event(&window->event_signal, SWC_WINDOW_DESTROYED, NULL);
60+    swc_surface_set_class(INTERNAL(window)->surface, NULL);
61+    INTERNAL(window)->surface->window = NULL;
62 }
63 
64 void swc_window_set_title(struct swc_window * window,
+1, -2
 1@@ -41,7 +41,6 @@ struct swc_window_internal
 2     struct swc_window base;
 3 
 4     struct swc_surface * surface;
 5-    struct wl_listener surface_destroy_listener;
 6     const struct swc_window_impl * impl;
 7 };
 8 
 9@@ -51,7 +50,7 @@ bool swc_window_initialize(struct swc_window * window,
10                            const struct swc_window_impl * impl,
11                            struct swc_surface * surface);
12 
13-struct swc_window * swc_window_get(struct swc_surface * surface);
14+void swc_window_finalize(struct swc_window * window);
15 
16 void swc_window_set_title(struct swc_window * window,
17                           const char * title, size_t length);