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: