[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

wayland: Changes to 'debian-unstable'



 .gitignore                            |    1 
 Makefile.am                           |   46 
 configure.ac                          |    4 
 cursor/os-compatibility.c             |    2 
 debian/changelog                      |    7 
 debian/libwayland-server0.symbols     |    3 
 doc/doxygen/Makefile.am               |    1 
 doc/doxygen/wayland.doxygen.in        |    3 
 doc/publican/sources/Client.xml       |    2 
 protocol/wayland.xml                  |  239 -
 src/connection.c                      |    2 
 src/dtddata.S                         |   35 
 src/scanner.c                         |   71 
 src/wayland-client-uninstalled.pc.in  |    3 
 src/wayland-client.c                  |    2 
 src/wayland-private.h                 |   24 
 src/wayland-scanner-uninstalled.pc.in |    2 
 src/wayland-server-core.h             |   31 
 src/wayland-server-uninstalled.pc.in  |    3 
 src/wayland-server.c                  |  339 +-
 src/wayland-shm.c                     |    2 
 src/wayland-util.c                    |    1 
 src/wayland-util.h                    |  559 ++-
 tests/array-test.c                    |   34 
 tests/connection-test.c               |   35 
 tests/data/example-client.h           | 5587 ++++++++++++++++++++++++++++++++++
 tests/data/example-code.c             |  507 +++
 tests/data/example-server.h           | 4335 ++++++++++++++++++++++++++
 tests/data/example.xml                | 2746 ++++++++++++++++
 tests/data/small-client-core.h        |  195 +
 tests/data/small-client.h             |  195 +
 tests/data/small-code-core.c          |   61 
 tests/data/small-code.c               |   61 
 tests/data/small-server-core.h        |  154 
 tests/data/small-server.h             |  154 
 tests/data/small.xml                  |   58 
 tests/display-test.c                  |  140 
 tests/interface-test.c                |   50 
 tests/message-test.c                  |   39 
 tests/newsignal-test.c                |  337 ++
 tests/scanner-test.sh                 |   51 
 tests/test-runner.c                   |    3 
 42 files changed, 15841 insertions(+), 283 deletions(-)

New commits:
commit 7eb795ae271fc3618414787ca0203b23754a78fb
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Thu Aug 3 11:25:43 2017 +0300

    release to unstable

diff --git a/debian/changelog b/debian/changelog
index dd3a883..5df2a6f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,9 @@
-wayland (1.13.0-1) UNRELEASED; urgency=medium
+wayland (1.13.0-1) unstable; urgency=medium
 
   * New upstream release. (Closes: #870566)
   * libwayland-server0.symbols: Updated.
 
- -- Timo Aaltonen <tjaalton@debian.org>  Thu, 03 Aug 2017 10:50:40 +0300
+ -- Timo Aaltonen <tjaalton@debian.org>  Thu, 03 Aug 2017 11:25:29 +0300
 
 wayland (1.12.0-1) unstable; urgency=medium
 

commit de130bdbf8a605241786bac1974f604ccef5b67c
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Thu Aug 3 11:21:40 2017 +0300

    libwayland-server0.symbols: Updated.

diff --git a/debian/changelog b/debian/changelog
index 7dfc486..dd3a883 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
 wayland (1.13.0-1) UNRELEASED; urgency=medium
 
   * New upstream release. (Closes: #870566)
+  * libwayland-server0.symbols: Updated.
 
  -- Timo Aaltonen <tjaalton@debian.org>  Thu, 03 Aug 2017 10:50:40 +0300
 
diff --git a/debian/libwayland-server0.symbols b/debian/libwayland-server0.symbols
index 7187d58..932dfa2 100644
--- a/debian/libwayland-server0.symbols
+++ b/debian/libwayland-server0.symbols
@@ -48,6 +48,7 @@ libwayland-server.so.0 libwayland-server0 #MINVER#
  wl_display_next_serial@Base 1.0.2
  wl_display_remove_global@Base 1.0.2
  wl_display_run@Base 1.0.2
+ wl_display_set_global_filter@Base 1.13.0
  wl_display_terminate@Base 1.0.2
  wl_event_loop_add_destroy_listener@Base 1.0.4
  wl_event_loop_add_fd@Base 1.0.2
@@ -66,6 +67,8 @@ libwayland-server.so.0 libwayland-server0 #MINVER#
  wl_event_source_timer_update@Base 1.0.2
  wl_global_create@Base 1.2.0
  wl_global_destroy@Base 1.2.0
+ wl_global_get_interface@Base 1.13.0
+ wl_global_get_user_data@Base 1.13.0
  wl_keyboard_interface@Base 1.0.2
  wl_list_empty@Base 1.0.2
  wl_list_init@Base 1.0.2

commit 2d6fad29e42cdf4070e549f08faef0d53e3e2acf
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Thu Aug 3 10:53:24 2017 +0300

    update the changelog

diff --git a/debian/changelog b/debian/changelog
index 2f84b50..7dfc486 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+wayland (1.13.0-1) UNRELEASED; urgency=medium
+
+  * New upstream release. (Closes: #870566)
+
+ -- Timo Aaltonen <tjaalton@debian.org>  Thu, 03 Aug 2017 10:50:40 +0300
+
 wayland (1.12.0-1) unstable; urgency=medium
 
   * New upstream release. Closes: #840752.

commit 1361da9cd5a719b32d978485a29920429a31ed25
Author: Bryce Harrington <bryce@osg.samsung.com>
Date:   Tue Feb 21 13:27:16 2017 -0800

    configure.ac: bump to version 1.13.0 for the official release

diff --git a/configure.ac b/configure.ac
index c50027b..fcce4ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,8 +1,8 @@
 AC_PREREQ([2.64])
 
 m4_define([wayland_major_version],  [1])
-m4_define([wayland_minor_version], [12])
-m4_define([wayland_micro_version], [93])
+m4_define([wayland_minor_version], [13])
+m4_define([wayland_micro_version],  [0])
 m4_define([wayland_version],
           [wayland_major_version.wayland_minor_version.wayland_micro_version])
 

commit 24df0fb6b3835c3b4574847491eecae769af4c2c
Author: Bryce Harrington <bryce@osg.samsung.com>
Date:   Tue Feb 14 12:56:55 2017 -0800

    configure.ac: bump to version 1.12.93 for the RC1 release

diff --git a/configure.ac b/configure.ac
index 2a3d5e3..c50027b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ AC_PREREQ([2.64])
 
 m4_define([wayland_major_version],  [1])
 m4_define([wayland_minor_version], [12])
-m4_define([wayland_micro_version], [92])
+m4_define([wayland_micro_version], [93])
 m4_define([wayland_version],
           [wayland_major_version.wayland_minor_version.wayland_micro_version])
 

commit 6161d7dd0efd33339a90bdfbc6f2575ff16f1b2f
Author: Bryce Harrington <bryce@osg.samsung.com>
Date:   Tue Feb 7 15:14:56 2017 -0800

    configure.ac: bump to version 1.12.92 for the beta release

diff --git a/configure.ac b/configure.ac
index 7520b24..2a3d5e3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ AC_PREREQ([2.64])
 
 m4_define([wayland_major_version],  [1])
 m4_define([wayland_minor_version], [12])
-m4_define([wayland_micro_version], [91])
+m4_define([wayland_micro_version], [92])
 m4_define([wayland_version],
           [wayland_major_version.wayland_minor_version.wayland_micro_version])
 

commit 56f2dad6d2ac04e179d43d525f6213031dcb4d62
Author: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Date:   Wed Jan 25 14:24:44 2017 +0200

    wayland-server: hide wl_priv_signal from doxygen
    
    Fix this set of warnings appearing three times during a build:
    
    /home/pq/git/wayland/src/wayland-server.c:1868: warning: class
    `wl_priv_signal' for related function `wl_priv_signal_init' is not
    documented.
    /home/pq/git/wayland/src/wayland-server.c:1884: warning: class
    `wl_priv_signal' for related function `wl_priv_signal_add' is not
    documented.
    /home/pq/git/wayland/src/wayland-server.c:1899: warning: class
    `wl_priv_signal' for related function `wl_priv_signal_get' is not
    documented.
    
    Our Wayland docbook don't include private things, so make sure these do
    not end up there. This removes the mention of wl_priv_signal_emit from
    the Server API docbook. I have no idea why the other functions did not
    appear there.
    
    Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
    Reviewed-by: Yong Bakos <ybakos@humanoriented.com>

diff --git a/src/wayland-server.c b/src/wayland-server.c
index cdd46fa..6a8b3e4 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -1881,6 +1881,8 @@ wl_client_for_each_resource(struct wl_client *client,
 	wl_map_for_each(&client->objects, resource_iterator_helper, &context);
 }
 
+/** \cond INTERNAL */
+
 /** Initialize a wl_priv_signal object
  *
  * wl_priv_signal is a safer implementation of a signal type, with the same API
@@ -1972,6 +1974,8 @@ wl_priv_signal_emit(struct wl_priv_signal *signal, void *data)
 	}
 }
 
+/** \endcond INTERNAL */
+
 /** \cond */ /* Deprecated functions below. */
 
 uint32_t

commit 8fe8a2bb1e2b893bd39899f7481d5cf5fa303b29
Author: Yong Bakos <ybakos@humanoriented.com>
Date:   Wed Nov 23 07:38:01 2016 -0800

    tests: Test wl_argument_from_va_list
    
    connection-test.c did not cover wl_argument_from_va_list, so add one
    test that specifically tests this method.
    
    Signed-off-by: Yong Bakos <ybakos@humanoriented.com>
    Reviewed-by: Daniel Stone <daniels@collabora.com>

diff --git a/tests/connection-test.c b/tests/connection-test.c
index 3e34f77..1c688f1 100644
--- a/tests/connection-test.c
+++ b/tests/connection-test.c
@@ -130,6 +130,41 @@ TEST(connection_queue)
 	close(s[1]);
 }
 
+static void
+va_list_wrapper(const char *signature, union wl_argument *args, int count, ...)
+{
+	va_list ap;
+	va_start(ap, count);
+	wl_argument_from_va_list(signature, args, count, ap);
+	va_end(ap);
+}
+
+TEST(argument_from_va_list)
+{
+	union wl_argument args[WL_CLOSURE_MAX_ARGS];
+	struct wl_object fake_object;
+	struct wl_array fake_array;
+
+	va_list_wrapper("i", args, 1, 100);
+	assert(args[0].i == 100);
+
+	va_list_wrapper("is", args, 2, 101, "value");
+	assert(args[0].i == 101);
+	assert(strcmp(args[1].s, "value") == 0);
+
+	va_list_wrapper("?iuf?sonah", args, 8,
+			102, 103, wl_fixed_from_int(104), "value",
+			&fake_object, 105, &fake_array, 106);
+	assert(args[0].i == 102);
+	assert(args[1].u == 103);
+	assert(args[2].f == wl_fixed_from_int(104));
+	assert(strcmp(args[3].s, "value") == 0);
+	assert(args[4].o == &fake_object);
+	assert(args[5].n == 105);
+	assert(args[6].a == &fake_array);
+	assert(args[7].h == 106);
+}
+
 struct marshal_data {
 	struct wl_connection *read_connection;
 	struct wl_connection *write_connection;

commit e89d0a66843eb3cb4d888c594ad87ef731e51697
Author: Yong Bakos <ybakos@humanoriented.com>
Date:   Mon Jan 23 06:16:30 2017 -0800

    dtddata: Use standard permission notice
    
    Signed-off-by: Yong Bakos <ybakos@humanoriented.com>
    Reviewed-by: Daniel Stone <daniels@collabora.com>

diff --git a/src/dtddata.S b/src/dtddata.S
index ce51133..2405066 100644
--- a/src/dtddata.S
+++ b/src/dtddata.S
@@ -1,23 +1,26 @@
 /*
  * Copyright � 2015 Collabora, Ltd.
  *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the copyright holders not be used in
- * advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission.  The copyright holders make
- * no representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
  *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
  */
 
 /*

commit de908658945ef8e13b27b32a7a69f14b3f9356df
Author: Derek Foreman <derekf@osg.samsung.com>
Date:   Tue Jan 24 12:07:21 2017 -0600

    wayland-server: log an error for events with wrong client objects
    
    Check that all the objects in an event belong to the same client as
    the resource posting it.  This prevents a compositor from accidentally
    mixing client objects and posting an event that causes a client to
    abort with a cryptic message.
    
    Instead the client will now be disconnected as it is when the compositor
    tries to send a null for a non-nullable object, and a log message
    will be printed by the compositor.
    
    Reviewed-by: Yong Bakos <ybakos@humanoriented.com>
    Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
    Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
    Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>

diff --git a/src/wayland-server.c b/src/wayland-server.c
index 0a5eacb..cdd46fa 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -168,6 +168,36 @@ log_closure(struct wl_resource *resource,
 	}
 }
 
+static bool
+verify_objects(struct wl_resource *resource, uint32_t opcode,
+	       union wl_argument *args)
+{
+	struct wl_object *object = &resource->object;
+	const char *signature = object->interface->events[opcode].signature;
+	struct argument_details arg;
+	struct wl_resource *res;
+	int count, i;
+
+	count = arg_count_for_signature(signature);
+	for (i = 0; i < count; i++) {
+		signature = get_next_argument(signature, &arg);
+		switch (arg.type) {
+		case 'n':
+		case 'o':
+			res = (struct wl_resource *) (args[i].o);
+			if (res && res->client != resource->client) {
+				wl_log("compositor bug: The compositor "
+				       "tried to use an object from one "
+				       "client in a '%s.%s' for a different "
+				       "client.\n", object->interface->name,
+				       object->interface->events[opcode].name);
+				return false;
+			}
+		}
+	}
+	return true;
+}
+
 static void
 handle_array(struct wl_resource *resource, uint32_t opcode,
 	     union wl_argument *args,
@@ -179,6 +209,11 @@ handle_array(struct wl_resource *resource, uint32_t opcode,
 	if (resource->client->error)
 		return;
 
+	if (!verify_objects(resource, opcode, args)) {
+		resource->client->error = 1;
+		return;
+	}
+
 	closure = wl_closure_marshal(object, opcode, args,
 				     &object->interface->events[opcode]);
 

commit efae9532e82e1faeb737fe0d3cf5932026ce1e6f
Author: Derek Foreman <derekf@osg.samsung.com>
Date:   Tue Jan 24 12:07:20 2017 -0600

    server: Disallow sending events to clients after posting an error
    
    Until now, we haven't done anything to prevent sending additional
    events to clients after posting an error.
    
    Acked-by: Daniel Stone <daniels@collabora.com>
    Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
    Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>

diff --git a/src/wayland-server.c b/src/wayland-server.c
index a981fda..0a5eacb 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -176,6 +176,9 @@ handle_array(struct wl_resource *resource, uint32_t opcode,
 	struct wl_closure *closure;
 	struct wl_object *object = &resource->object;
 
+	if (resource->client->error)
+		return;
+
 	closure = wl_closure_marshal(object, opcode, args,
 				     &object->interface->events[opcode]);
 
@@ -249,8 +252,6 @@ wl_resource_post_error(struct wl_resource *resource,
 	vsnprintf(buffer, sizeof buffer, msg, ap);
 	va_end(ap);
 
-	client->error = 1;
-
 	/*
 	 * When a client aborts, its resources are destroyed in id order,
 	 * which means the display resource is destroyed first. If destruction
@@ -258,11 +259,12 @@ wl_resource_post_error(struct wl_resource *resource,
 	 * with a NULL display_resource. Do not try to send errors to an
 	 * already dead client.
 	 */
-	if (!client->display_resource)
+	if (client->error || !client->display_resource)
 		return;
 
 	wl_resource_post_event(client->display_resource,
 			       WL_DISPLAY_ERROR, resource, code, buffer);
+	client->error = 1;
 }
 
 static int

commit 5fbc9daa409371d15ffb9012cc21dddc934fad4a
Author: Derek Foreman <derekf@osg.samsung.com>
Date:   Tue Jan 24 12:07:19 2017 -0600

    server: Refactor array send functions
    
    These have grown a little in size but are almost identical, factor
    out the common code.
    
    Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
    Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>

diff --git a/src/wayland-server.c b/src/wayland-server.c
index ac634da..a981fda 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -168,9 +168,10 @@ log_closure(struct wl_resource *resource,
 	}
 }
 
-WL_EXPORT void
-wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
-			     union wl_argument *args)
+static void
+handle_array(struct wl_resource *resource, uint32_t opcode,
+	     union wl_argument *args,
+	     int (*send_func)(struct wl_closure *, struct wl_connection *))
 {
 	struct wl_closure *closure;
 	struct wl_object *object = &resource->object;
@@ -183,7 +184,7 @@ wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
 		return;
 	}
 
-	if (wl_closure_send(closure, resource->client->connection))
+	if (send_func(closure, resource->client->connection))
 		resource->client->error = 1;
 
 	log_closure(resource, closure, true);
@@ -192,6 +193,13 @@ wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
 }
 
 WL_EXPORT void
+wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
+			     union wl_argument *args)
+{
+	handle_array(resource, opcode, args, wl_closure_send);
+}
+
+WL_EXPORT void
 wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
 {
 	union wl_argument args[WL_CLOSURE_MAX_ARGS];
@@ -211,23 +219,7 @@ WL_EXPORT void
 wl_resource_queue_event_array(struct wl_resource *resource, uint32_t opcode,
 			      union wl_argument *args)
 {
-	struct wl_closure *closure;
-	struct wl_object *object = &resource->object;
-
-	closure = wl_closure_marshal(object, opcode, args,
-				     &object->interface->events[opcode]);
-
-	if (closure == NULL) {
-		resource->client->error = 1;
-		return;
-	}
-
-	if (wl_closure_queue(closure, resource->client->connection))
-		resource->client->error = 1;
-
-	log_closure(resource, closure, true);
-
-	wl_closure_destroy(closure);
+	handle_array(resource, opcode, args, wl_closure_queue);
 }
 
 WL_EXPORT void

commit c44eed1c064999f1e0297088bacd56c602dee2eb
Author: Giulio Camuffo <giuliocamuffo@gmail.com>
Date:   Tue Jan 24 16:34:30 2017 +0200

    server: use the new wl_priv_signal for wl_resource
    
    The old wl_signal is kept for backwards compatibility, as that is also
    present in the deprecated public wl_resource struct, and that must be
    kept working.
    
    Signed-off-by: Giulio Camuffo <giulio.camuffo@kdab.com>
    Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>

diff --git a/src/wayland-server.c b/src/wayland-server.c
index 06f8ba2..ac634da 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -120,11 +120,16 @@ struct wl_resource {
 	struct wl_object object;
 	wl_resource_destroy_func_t destroy;
 	struct wl_list link;
-	struct wl_signal destroy_signal;
+	/* Unfortunately some users of libwayland (e.g. mesa) still use the
+	 * deprecated wl_resource struct, even if creating it with the new
+	 * wl_resource_create(). So we cannot change the layout of the struct
+	 * unless after the data field. */
+	struct wl_signal deprecated_destroy_signal;
 	struct wl_client *client;
 	void *data;
 	int version;
 	wl_dispatcher_func_t dispatcher;
+	struct wl_priv_signal destroy_signal;
 };
 
 struct wl_protocol_logger {
@@ -600,6 +605,31 @@ wl_resource_post_no_memory(struct wl_resource *resource)
 			       WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
 }
 
+/** Detect if a wl_resource uses the deprecated public definition.
+ *
+ * Before Wayland 1.2.0, the definition of struct wl_resource was public.
+ * It was made opaque just before 1.2.0, and later new fields were added.
+ * The new fields cannot be accessed if a program is using the deprecated
+ * defition, as there would not be memory allocated for them.
+ *
+ * The creation pattern for the deprecated definition was wl_resource_init()
+ * followed by wl_client_add_resource(). wl_resource_init() was an inline
+ * function and no longer exists, but binaries might still carry it.
+ * wl_client_add_resource() still exists for ABI compatiblity.
+ */
+static bool
+resource_is_deprecated(struct wl_resource *resource)
+{
+	struct wl_map *map = &resource->client->objects;
+	int id = resource->object.id;
+
+	/* wl_client_add_resource() marks deprecated resources with the flag. */
+	if (wl_map_lookup_flags(map, id) & WL_MAP_ENTRY_LEGACY)
+		return true;
+
+	return false;
+}
+
 static enum wl_iterator_result
 destroy_resource(void *element, void *data)
 {
@@ -607,7 +637,11 @@ destroy_resource(void *element, void *data)
 	struct wl_client *client = resource->client;
 	uint32_t flags;
 
-	wl_signal_emit(&resource->destroy_signal, resource);
+	wl_signal_emit(&resource->deprecated_destroy_signal, resource);
+	/* Don't emit the new signal for deprecated resources, as that would
+	 * access memory outside the bounds of the deprecated struct */
+	if (!resource_is_deprecated(resource))
+		wl_priv_signal_emit(&resource->destroy_signal, resource);
 
 	flags = wl_map_lookup_flags(&client->objects, resource->object.id);
 	if (resource->destroy)
@@ -719,14 +753,19 @@ WL_EXPORT void
 wl_resource_add_destroy_listener(struct wl_resource *resource,
 				 struct wl_listener * listener)
 {
-	wl_signal_add(&resource->destroy_signal, listener);
+	if (resource_is_deprecated(resource))
+		wl_signal_add(&resource->deprecated_destroy_signal, listener);
+	else
+		wl_priv_signal_add(&resource->destroy_signal, listener);
 }
 
 WL_EXPORT struct wl_listener *
 wl_resource_get_destroy_listener(struct wl_resource *resource,
 				 wl_notify_func_t notify)
 {
-	return wl_signal_get(&resource->destroy_signal, notify);
+	if (resource_is_deprecated(resource))
+		return wl_signal_get(&resource->deprecated_destroy_signal, notify);
+	return wl_priv_signal_get(&resource->destroy_signal, notify);
 }
 
 /** Retrieve the interface name (class) of a resource object.
@@ -1559,7 +1598,8 @@ wl_resource_create(struct wl_client *client,
 	resource->object.interface = interface;
 	resource->object.implementation = NULL;
 
-	wl_signal_init(&resource->destroy_signal);
+	wl_signal_init(&resource->deprecated_destroy_signal);
+	wl_priv_signal_init(&resource->destroy_signal);
 
 	resource->destroy = NULL;
 	resource->client = client;
@@ -1927,7 +1967,7 @@ wl_client_add_resource(struct wl_client *client,
 	}
 
 	resource->client = client;
-	wl_signal_init(&resource->destroy_signal);
+	wl_signal_init(&resource->deprecated_destroy_signal);
 
 	return resource->object.id;
 }

commit 7454aa9bb9569a1d63f6bcb1938e165ea370a4a5
Author: Giulio Camuffo <giuliocamuffo@gmail.com>
Date:   Tue Jan 24 16:34:29 2017 +0200

    server: use the new wl_priv_signal in wl_client
    
    Signed-off-by: Giulio Camuffo <giulio.camuffo@kdab.com>
    Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>

diff --git a/src/wayland-server.c b/src/wayland-server.c
index 1482d5e..06f8ba2 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -78,10 +78,10 @@ struct wl_client {
 	uint32_t mask;
 	struct wl_list link;
 	struct wl_map objects;
-	struct wl_signal destroy_signal;
+	struct wl_priv_signal destroy_signal;
 	struct ucred ucred;
 	int error;
-	struct wl_signal resource_created_signal;
+	struct wl_priv_signal resource_created_signal;
 };
 
 struct wl_display {
@@ -460,7 +460,7 @@ wl_client_create(struct wl_display *display, int fd)
 	if (client == NULL)
 		return NULL;
 
-	wl_signal_init(&client->resource_created_signal);
+	wl_priv_signal_init(&client->resource_created_signal);
 	client->display = display;
 	client->source = wl_event_loop_add_fd(display->loop, fd,
 					      WL_EVENT_READABLE,
@@ -483,7 +483,7 @@ wl_client_create(struct wl_display *display, int fd)
 	if (wl_map_insert_at(&client->objects, 0, 0, NULL) < 0)
 		goto err_map;
 
-	wl_signal_init(&client->destroy_signal);
+	wl_priv_signal_init(&client->destroy_signal);
 	if (bind_display(client, display) < 0)
 		goto err_map;
 
@@ -745,14 +745,14 @@ WL_EXPORT void
 wl_client_add_destroy_listener(struct wl_client *client,
 			       struct wl_listener *listener)
 {
-	wl_signal_add(&client->destroy_signal, listener);
+	wl_priv_signal_add(&client->destroy_signal, listener);
 }
 
 WL_EXPORT struct wl_listener *
 wl_client_get_destroy_listener(struct wl_client *client,
 			       wl_notify_func_t notify)
 {
-	return wl_signal_get(&client->destroy_signal, notify);
+	return wl_priv_signal_get(&client->destroy_signal, notify);
 }
 
 WL_EXPORT void
@@ -760,7 +760,7 @@ wl_client_destroy(struct wl_client *client)
 {
 	uint32_t serial = 0;
 
-	wl_signal_emit(&client->destroy_signal, client);
+	wl_priv_signal_emit(&client->destroy_signal, client);
 
 	wl_client_flush(client);
 	wl_map_for_each(&client->objects, destroy_resource, &serial);
@@ -1575,7 +1575,7 @@ wl_resource_create(struct wl_client *client,
 		return NULL;
 	}
 
-	wl_signal_emit(&client->resource_created_signal, resource);
+	wl_priv_signal_emit(&client->resource_created_signal, resource);
 	return resource;
 }
 
@@ -1763,7 +1763,7 @@ WL_EXPORT void
 wl_client_add_resource_created_listener(struct wl_client *client,
 					struct wl_listener *listener)
 {
-	wl_signal_add(&client->resource_created_signal, listener);
+	wl_priv_signal_add(&client->resource_created_signal, listener);
 }
 
 struct wl_resource_iterator_context {

commit 5e6eb032294ecdee889600c604dfcaab0ffb9398
Author: Giulio Camuffo <giuliocamuffo@gmail.com>
Date:   Tue Jan 24 16:34:28 2017 +0200

    server: add a safer signal type and port wl_display to it
    
    wl_list_for_each_safe, which is used by wl_signal_emit is not really
    safe. If a signal has two listeners, and the first one removes and
    re-inits the second one, it would enter an infinite loop, which was hit
    in weston on resource destruction, which emits a signal.
    This commit adds a new version of wl_signal, called wl_priv_signal,
    which is private in wayland-server.c and which does not have this problem.
    The old wl_signal cannot be improved without breaking backwards compatibility.
    
    Signed-off-by: Giulio Camuffo <giulio.camuffo@kdab.com>
    Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>

diff --git a/Makefile.am b/Makefile.am
index d78a0ca..d0c8bd3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -159,6 +159,7 @@ built_test_programs =				\
 	socket-test				\
 	queue-test				\
 	signal-test				\
+	newsignal-test				\
 	resources-test				\
 	message-test				\
 	headers-test				\
@@ -226,6 +227,9 @@ queue_test_SOURCES = tests/queue-test.c
 queue_test_LDADD = libtest-runner.la
 signal_test_SOURCES = tests/signal-test.c
 signal_test_LDADD = libtest-runner.la
+# wayland-server.c is needed here to access wl_priv_* functions
+newsignal_test_SOURCES = tests/newsignal-test.c src/wayland-server.c
+newsignal_test_LDADD = libtest-runner.la
 resources_test_SOURCES = tests/resources-test.c
 resources_test_LDADD = libtest-runner.la
 message_test_SOURCES = tests/message-test.c
diff --git a/src/wayland-private.h b/src/wayland-private.h
index 676b181..434cb04 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -35,6 +35,7 @@
 #define WL_HIDE_DEPRECATED 1
 
 #include "wayland-util.h"
+#include "wayland-server-core.h"
 
 /* Invalid memory address */
 #define WL_ARRAY_POISON_PTR (void *) 4
@@ -233,4 +234,21 @@ zalloc(size_t s)
 	return calloc(1, s);
 }
 
+struct wl_priv_signal {
+	struct wl_list listener_list;
+	struct wl_list emit_list;
+};
+
+void
+wl_priv_signal_init(struct wl_priv_signal *signal);
+
+void
+wl_priv_signal_add(struct wl_priv_signal *signal, struct wl_listener *listener);
+
+struct wl_listener *
+wl_priv_signal_get(struct wl_priv_signal *signal, wl_notify_func_t notify);
+
+void
+wl_priv_signal_emit(struct wl_priv_signal *signal, void *data);
+
 #endif
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 4360874..1482d5e 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -97,8 +97,8 @@ struct wl_display {
 	struct wl_list client_list;
 	struct wl_list protocol_loggers;
 
-	struct wl_signal destroy_signal;
-	struct wl_signal create_client_signal;
+	struct wl_priv_signal destroy_signal;
+	struct wl_priv_signal create_client_signal;
 
 	struct wl_array additional_shm_formats;
 
@@ -489,7 +489,7 @@ wl_client_create(struct wl_display *display, int fd)
 
 	wl_list_insert(display->client_list.prev, &client->link);
 
-	wl_signal_emit(&display->create_client_signal, client);
+	wl_priv_signal_emit(&display->create_client_signal, client);
 
 	return client;
 
@@ -942,8 +942,8 @@ wl_display_create(void)
 	wl_list_init(&display->registry_resource_list);
 	wl_list_init(&display->protocol_loggers);
 
-	wl_signal_init(&display->destroy_signal);
-	wl_signal_init(&display->create_client_signal);
+	wl_priv_signal_init(&display->destroy_signal);
+	wl_priv_signal_init(&display->create_client_signal);
 
 	display->id = 1;
 	display->serial = 0;
@@ -1008,7 +1008,7 @@ wl_display_destroy(struct wl_display *display)
 	struct wl_socket *s, *next;
 	struct wl_global *global, *gnext;
 
-	wl_signal_emit(&display->destroy_signal, display);
+	wl_priv_signal_emit(&display->destroy_signal, display);
 
 	wl_list_for_each_safe(s, next, &display->socket_list, link) {
 		wl_socket_destroy(s);
@@ -1478,7 +1478,7 @@ WL_EXPORT void
 wl_display_add_destroy_listener(struct wl_display *display,
 				struct wl_listener *listener)
 {
-	wl_signal_add(&display->destroy_signal, listener);
+	wl_priv_signal_add(&display->destroy_signal, listener);
 }
 
 /** Registers a listener for the client connection signal.
@@ -1496,14 +1496,14 @@ WL_EXPORT void
 wl_display_add_client_created_listener(struct wl_display *display,
 					struct wl_listener *listener)
 {
-	wl_signal_add(&display->create_client_signal, listener);
+	wl_priv_signal_add(&display->create_client_signal, listener);
 }
 
 WL_EXPORT struct wl_listener *
 wl_display_get_destroy_listener(struct wl_display *display,
 				wl_notify_func_t notify)
 {
-	return wl_signal_get(&display->destroy_signal, notify);
+	return wl_priv_signal_get(&display->destroy_signal, notify);
 }
 
 WL_EXPORT void
@@ -1812,6 +1812,97 @@ wl_client_for_each_resource(struct wl_client *client,
 	wl_map_for_each(&client->objects, resource_iterator_helper, &context);
 }
 
+/** Initialize a wl_priv_signal object
+ *
+ * wl_priv_signal is a safer implementation of a signal type, with the same API
+ * as wl_signal, but kept as a private utility of libwayland-server.
+ * It is safer because listeners can be removed from within wl_priv_signal_emit()
+ * without corrupting the signal's list.
+ *
+ * Before passing a wl_priv_signal object to any other function it must be
+ * initialized by useing wl_priv_signal_init().
+ *
+ * \memberof wl_priv_signal
+ */
+void
+wl_priv_signal_init(struct wl_priv_signal *signal)
+{
+	wl_list_init(&signal->listener_list);
+	wl_list_init(&signal->emit_list);
+}
+
+/** Add a listener to a signal
+ *
+ * The new listener will be called when calling wl_signal_emit(). If a listener is
+ * added to the signal while wl_signal_emit() is running it will be called from
+ * the next time wl_priv_signal_emit() is called.
+ * To remove a listener call wl_list_remove() on its link member.
+ *
+ * \memberof wl_priv_signal
+ */
+void
+wl_priv_signal_add(struct wl_priv_signal *signal, struct wl_listener *listener)
+{
+	wl_list_insert(signal->listener_list.prev, &listener->link);
+}
+
+/** Get a listener added to a signal
+ *
+ * Returns the listener added to the given \a signal and with the given
+ * \a notify function, or NULL if there isn't any.
+ * Calling this function from withing wl_priv_signal_emit() is safe and will
+ * return the correct value.
+ *
+ * \memberof wl_priv_signal
+ */
+struct wl_listener *
+wl_priv_signal_get(struct wl_priv_signal *signal, wl_notify_func_t notify)
+{
+	struct wl_listener *l;
+
+	wl_list_for_each(l, &signal->listener_list, link)
+		if (l->notify == notify)
+			return l;
+	wl_list_for_each(l, &signal->emit_list, link)
+		if (l->notify == notify)
+			return l;
+
+	return NULL;
+}
+
+/** Emit the signal, calling all the installed listeners
+ *
+ * Iterate over all the listeners added to this \a signal and call
+ * their \a notify function pointer, passing on the given \a data.
+ * Removing or adding a listener from within wl_priv_signal_emit()
+ * is safe.
+ */
+void
+wl_priv_signal_emit(struct wl_priv_signal *signal, void *data)
+{
+	struct wl_listener *l;
+	struct wl_list *pos;
+
+	wl_list_insert_list(&signal->emit_list, &signal->listener_list);
+	wl_list_init(&signal->listener_list);
+
+	/* Take every element out of the list and put them in a temporary list.
+	 * This way, the 'it' func can remove any element it wants from the list
+	 * without troubles, because we always get the first element, not the
+	 * one after the current, which may be invalid.
+	 * wl_list_for_each_safe tries to be safe but it fails: it works fine
+	 * if the current item is removed, but not if the next one is. */
+	while (!wl_list_empty(&signal->emit_list)) {
+		pos = signal->emit_list.next;


Reply to: