<html><head></head><body><div class="gmail_quote">On 20 November 2018 8:02:50 pm NZDT, Christopher James Halse Rogers <christopher.halse.rogers@canonical.com> wrote:<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<pre class="k9mail">Many languages such as C++ or Rust have an unwinding error-reporting<br>mechanism. Code in these languages can (and must!) wrap request handling<br>callbacks in unwind guards to avoid undefined behaviour.<br><br>As a consequence such code will detect internal server errors, but have<br>no way to communicate such failures to the client.<br><br>This adds a WL_DISPLAY_ERROR_IMPLEMENTATION error to wl_display so that<br>such code can notify (and disconnect) clients which hit internal bugs.<br>While servers can currently abuse other wl_display errors for the same<br>effect, adding an explicit error code allows clients to tell the<br>difference between errors which are their fault and errors which are the<br>server's fault. This is particularly interesting for automated bug<br>reporting.<br><br>v2: Rename error from "internal" to "implementation", in sympathy with<br> X11's BadImplementation error.<br> Add more justification in the commit message.<br><br>Signed-off-by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com><br>Acked-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk><hr> protocol/wayland.xml | 2 ++<br> src/wayland-client.c | 3 +++<br> src/wayland-server-core.h | 4 ++++<br> src/wayland-server.c | 24 +++++++++++++++++++++++<br> tests/display-test.c | 40 +++++++++++++++++++++++++++++++++++++++<br> 5 files changed, 73 insertions(+)<br><br>diff --git a/protocol/wayland.xml b/protocol/wayland.xml<br>index 141038b..754b789 100644<br>--- a/protocol/wayland.xml<br>+++ b/protocol/wayland.xml<br>@@ -94,6 +94,8 @@<br> summary="method doesn't exist on the specified interface"/><br> <entry name="no_memory" value="2"<br> summary="server is out of memory"/><br>+ <entry name="implementation" value="3"<br>+ summary="implementation error in compositor"/><br> </enum><br> <br> <event name="delete_id"><br>diff --git a/src/wayland-client.c b/src/wayland-client.c<br>index 0ccfc66..b0805f1 100644<br>--- a/src/wayland-client.c<br>+++ b/src/wayland-client.c<br>@@ -185,6 +185,9 @@ display_protocol_error(struct wl_display *display, uint32_t code,<br> case WL_DISPLAY_ERROR_NO_MEMORY:<br> err = ENOMEM;<br> break;<br>+ case WL_DISPLAY_ERROR_IMPLEMENTATION:<br>+ err = EPROTO;<br>+ break;<br> default:<br> err = EFAULT;<br> }<br>diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h<br>index 2e725d9..3e0272b 100644<br>--- a/src/wayland-server-core.h<br>+++ b/src/wayland-server-core.h<br>@@ -324,6 +324,10 @@ wl_client_get_object(struct wl_client *client, uint32_t id);<br> void<br> wl_client_post_no_memory(struct wl_client *client);<br> <br>+void<br>+wl_client_post_implementation_error(struct wl_client *client,<br>+ const char* msg, ...) WL_PRINTF(2,3);<br>+<br> void<br> wl_client_add_resource_created_listener(struct wl_client *client,<br> struct wl_listener *listener);<br>diff --git a/src/wayland-server.c b/src/wayland-server.c<br>index c0ad229..19f6a76 100644<br>--- a/src/wayland-server.c<br>+++ b/src/wayland-server.c<br>@@ -650,6 +650,30 @@ wl_client_post_no_memory(struct wl_client *client)<br> WL_DISPLAY_ERROR_NO_MEMORY, "no memory");<br> }<br> <br>+/** Report an internal server error<br>+ *<br>+ * \param client The client object<br>+ * \param msg A printf-style format string<br>+ * \param ... Format string arguments<br>+ *<br>+ * Report an unspecified internal implementation error and disconnect<br>+ * the client.<br>+ *<br>+ * \memberof wl_client<br>+ */<br>+WL_EXPORT void<br>+wl_client_post_implementation_error(struct wl_client *client,<br>+ char const *msg, ...)<br>+{<br>+ va_list ap;<br>+<br>+ va_start(ap, msg);<br>+ wl_resource_post_error_vargs(client->display_resource,<br>+ WL_DISPLAY_ERROR_IMPLEMENTATION,<br>+ msg, ap);<br>+ va_end(ap);<br>+}<br>+<br> WL_EXPORT void<br> wl_resource_post_no_memory(struct wl_resource *resource)<br> {<br>diff --git a/tests/display-test.c b/tests/display-test.c<br>index 9b49a0e..6d98cc7 100644<br>--- a/tests/display-test.c<br>+++ b/tests/display-test.c<br>@@ -419,6 +419,46 @@ TEST(post_nomem_tst)<br> display_destroy(d);<br> }<br> <br>+static void<br>+post_implementation_error_main(void)<br>+{<br>+ struct client *c = client_connect();<br>+ struct wl_seat *seat = client_get_seat(c);<br>+ uint32_t object_id, protocol_error;<br>+ const struct wl_interface *interface;<br>+<br>+ assert(stop_display(c, 1) == -1);<br>+ int err = wl_display_get_error(c->wl_display);<br>+ fprintf(stderr, "Err is %i\n", err);<br>+ assert(err == EPROTO);<br>+ protocol_error = wl_display_get_protocol_error(c->wl_display,<br>+ &interface,<br>+ &object_id);<br>+ assert(protocol_error == WL_DISPLAY_ERROR_IMPLEMENTATION);<br>+ assert(interface == &wl_display_interface);<br>+<br>+ wl_proxy_destroy((struct wl_proxy *) seat);<br>+ client_disconnect_nocheck(c);<br>+}<br>+<br>+TEST(post_internal_error_tst)<br>+{<br>+ struct display *d = display_create();<br>+ struct client_info *cl;<br>+<br>+ wl_global_create(d->wl_display, &wl_seat_interface,<br>+ 1, d, bind_seat);<br>+<br>+ cl = client_create_noarg(d, post_implementation_error_main);<br>+ display_run(d);<br>+<br>+ wl_client_post_implementation_error(cl->wl_client, "Error %i", 20);<br>+<br>+ display_resume(d);<br>+<br>+ display_destroy(d);<br>+}<br>+<br> static void<br> register_reading(struct wl_display *display)<br> {</pre></blockquote></div><br clear="all">Ping!<br><br>Is there anything I can do to make these patches more appealing?</body></html>