[PATCH weston 06/11] XWayland: Only initialise WM on signal from the server

Daniel Stone daniel at fooishbar.org
Tue Nov 6 22:51:40 PST 2012


To avoid deadlocks where the X server is blocked on a roundtrip for
information from the compositor, and the compositor is blocked waiting
for connection information from the X server in window manager init,
wait for a signal from the X server saying that it's now waiting for
clients to connect.

Requires a protocol version bump.

Signed-off-by: Daniel Stone <daniel at fooishbar.org>
---
 protocol/xserver.xml          |    4 +++-
 src/xwayland/launcher.c       |    9 +++++----
 src/xwayland/window-manager.c |   21 ++++++++++++++++++---
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/protocol/xserver.xml b/protocol/xserver.xml
index 9e25f5c..2900fef 100644
--- a/protocol/xserver.xml
+++ b/protocol/xserver.xml
@@ -1,6 +1,6 @@
 <protocol name="xserver">
 
-  <interface name="xserver" version="1">
+  <interface name="xserver" version="2">
     <request name="set_window_id">
       <arg name="surface" type="object" interface="wl_surface"/>
       <arg name="id" type="uint"/>
@@ -13,6 +13,8 @@
     <event name="listen_socket">
       <arg name="fd" type="fd"/>
     </event>
+
+    <request name="init_complete"/>
   </interface>
 
 </protocol>
diff --git a/src/xwayland/launcher.c b/src/xwayland/launcher.c
index 00f064e..63986b0 100644
--- a/src/xwayland/launcher.c
+++ b/src/xwayland/launcher.c
@@ -162,10 +162,11 @@ bind_xserver(struct wl_client *client,
 		wl_client_add_object(client, &xserver_interface,
 				     &xserver_implementation, id, wxs);
 
-	wxs->wm = weston_wm_create(wxs);
-	if (wxs->wm == NULL) {
-		weston_log("failed to create wm\n");
-	}
+	/* init_complete() wasn't added until version 2.  Try to do
+	 * our best with v1, even if it does usually mean a
+	 * deadlock. */
+	if (version == 1)
+		wxs->wm = weston_wm_create(wxs);
 
 	xserver_send_listen_socket(wxs->resource, wxs->abstract_fd);
 	xserver_send_listen_socket(wxs->resource, wxs->unix_fd);
diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index 57b4e3c..4d44527 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -811,8 +811,9 @@ weston_wm_handle_property_notify(struct weston_wm *wm, xcb_generic_event_t *even
 		read_and_dump_property(wm, property_notify->window,
 				       property_notify->atom);
 
-	if (property_notify->atom == wm->atom.net_wm_name ||
-	    property_notify->atom == XCB_ATOM_WM_NAME)
+	if (window &&
+	    (property_notify->atom == wm->atom.net_wm_name ||
+	     property_notify->atom == XCB_ATOM_WM_NAME))
 		weston_wm_window_schedule_repaint(window);
 }
 
@@ -886,6 +887,8 @@ weston_wm_handle_destroy_notify(struct weston_wm *wm, xcb_generic_event_t *event
 		return;
 
 	window = hash_table_lookup(wm->window_hash, destroy_notify->window);
+	if (!window)
+		return;
 	weston_wm_window_destroy(window);
 }
 
@@ -1686,6 +1689,18 @@ xserver_set_window_id(struct wl_client *client, struct wl_resource *resource,
 	xserver_map_shell_surface(wm, window);
 }
 
+static void xserver_init_complete(struct wl_client *client,
+				  struct wl_resource *resource)
+{
+	struct weston_xserver *wxs = resource->data;
+
+	wxs->wm = weston_wm_create(wxs);
+	if (!wxs->wm)
+		wl_resource_post_error(resource, WL_DISPLAY_ERROR_NO_MEMORY,
+				       "failed to start window manager\n");
+}
+
 const struct xserver_interface xserver_implementation = {
-	xserver_set_window_id
+	xserver_set_window_id,
+	xserver_init_complete
 };
-- 
1.7.10.4



More information about the wayland-devel mailing list