.gitignore | 1 Makefile.am | 6 configure.ac | 4 debian/changelog | 12 debian/libwayland-client0.symbols | 2 debian/libwayland-server0.symbols | 1 doc/publican/Makefile.am | 2 doc/publican/publican.cfg | 2 protocol/wayland.xml | 49 +++ src/connection.c | 2 src/event-loop.c | 4 src/scanner.c | 42 +-- src/wayland-client.c | 203 ++++++++++++---- src/wayland-client.h | 5 src/wayland-server.c | 228 ++++++++++++------ src/wayland-server.h | 5 tests/display-test.c | 465 +++++++++++++++++++++++++++++++++++++ tests/event-loop-test.c | 74 +++++ tests/queue-test.c | 201 +++++----------- tests/socket-test.c | 90 +++++++ tests/test-compositor.c | 472 ++++++++++++++++++++++++++++++++++++++ tests/test-compositor.h | 97 +++++++ 22 files changed, 1673 insertions(+), 294 deletions(-)
New commits: commit 89481aaf2190bd5d053f63a9b4d1d101cf154ab3 Author: Emilio Pozuelo Monfort <po...@debian.org> Date: Fri Sep 5 03:10:27 2014 +0200 Upload to experimental diff --git a/debian/changelog b/debian/changelog index 077abcf..6c5990f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,14 @@ -wayland (1.5.91-1) UNRELEASED; urgency=medium +wayland (1.5.91-1) experimental; urgency=medium + [ Andreas Henriksson ] * New upstream development release. * Update debian/libwayland-client0.symbols with two additions * Update debian/libwayland-server0.symbols with one addition - -- Andreas Henriksson <andr...@fatal.se> Sat, 23 Aug 2014 16:03:00 +0200 + [ Emilio Pozuelo Monfort ] + * Upload to experimental. + + -- Emilio Pozuelo Monfort <po...@debian.org> Fri, 05 Sep 2014 03:10:22 +0200 wayland (1.5.0-1) unstable; urgency=medium commit 350b32ee80b2bd9534335123bb7ded7acea7ea3c Author: Andreas Henriksson <andr...@fatal.se> Date: Sat Aug 23 16:12:01 2014 +0200 Update debian/libwayland-server0.symbols with one addition diff --git a/debian/changelog b/debian/changelog index 242f40d..077abcf 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ wayland (1.5.91-1) UNRELEASED; urgency=medium * New upstream development release. * Update debian/libwayland-client0.symbols with two additions + * Update debian/libwayland-server0.symbols with one addition -- Andreas Henriksson <andr...@fatal.se> Sat, 23 Aug 2014 16:03:00 +0200 diff --git a/debian/libwayland-server0.symbols b/debian/libwayland-server0.symbols index 27cc810..8a2f372 100644 --- a/debian/libwayland-server0.symbols +++ b/debian/libwayland-server0.symbols @@ -27,6 +27,7 @@ libwayland-server.so.0 libwayland-server0 #MINVER# wl_display_add_global@Base 1.0.2 wl_display_add_shm_format@Base 1.3.0 wl_display_add_socket@Base 1.0.2 + wl_display_add_socket_auto@Base 1.5.91 wl_display_create@Base 1.0.2 wl_display_destroy@Base 1.0.2 wl_display_flush_clients@Base 1.0.2 commit f9855ae74860d318ec048c3541dd8878198450c8 Author: Andreas Henriksson <andr...@fatal.se> Date: Sat Aug 23 16:09:51 2014 +0200 Update debian/libwayland-client0.symbols with two additions diff --git a/debian/changelog b/debian/changelog index 9dbce98..242f40d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ wayland (1.5.91-1) UNRELEASED; urgency=medium * New upstream development release. + * Update debian/libwayland-client0.symbols with two additions -- Andreas Henriksson <andr...@fatal.se> Sat, 23 Aug 2014 16:03:00 +0200 diff --git a/debian/libwayland-client0.symbols b/debian/libwayland-client0.symbols index 7401d54..15b4f8d 100644 --- a/debian/libwayland-client0.symbols +++ b/debian/libwayland-client0.symbols @@ -23,11 +23,13 @@ libwayland-client.so.0 libwayland-client0 #MINVER# wl_display_flush@Base 1.0.2 wl_display_get_error@Base 1.0.2 wl_display_get_fd@Base 1.0.2 + wl_display_get_protocol_error@Base 1.5.91 wl_display_interface@Base 1.0.2 wl_display_prepare_read@Base 1.2.0 wl_display_prepare_read_queue@Base 1.2.0 wl_display_read_events@Base 1.2.0 wl_display_roundtrip@Base 1.0.2 + wl_display_roundtrip_queue@Base 1.5.91 wl_event_queue_destroy@Base 1.0.2 wl_keyboard_interface@Base 1.0.2 wl_list_empty@Base 1.0.2 commit 42c3daa4ae31ddf9b7600b404c97e36d6cc7e9fd Author: Andreas Henriksson <andr...@fatal.se> Date: Sat Aug 23 16:05:50 2014 +0200 New upstream development release. diff --git a/debian/changelog b/debian/changelog index b5a1e92..9dbce98 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +wayland (1.5.91-1) UNRELEASED; urgency=medium + + * New upstream development release. + + -- Andreas Henriksson <andr...@fatal.se> Sat, 23 Aug 2014 16:03:00 +0200 + wayland (1.5.0-1) unstable; urgency=medium * New upstream release. commit 6d0f298665e0f6b11a18ab6b6ccc49ba990b4b3e Author: Pekka Paalanen <pekka.paala...@collabora.co.uk> Date: Fri Aug 22 18:01:35 2014 +0300 configure.ac: Bump version to 1.5.91 for the alpha release Signed-off-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> diff --git a/configure.ac b/configure.ac index e16c5b5..d8e42d9 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], [5]) -m4_define([wayland_micro_version], [90]) +m4_define([wayland_micro_version], [91]) m4_define([wayland_version], [wayland_major_version.wayland_minor_version.wayland_micro_version]) commit 8c061d1b7e4fcdfe8d12887720ef129b8f921139 Author: Marek Chalupa <mchqwe...@gmail.com> Date: Fri Aug 22 14:28:59 2014 +0200 client: check for error in wl_display_read_events This prevents from blocking shown in one display test. Also, it makes sense to not proceed further in the code of the function when an error ocurred. v2. set errno put note about the errno into wl_display_prepare_read doc check for error with mutex locked v3. set errno to display->last_error check for the error only in wl_display_read_events. It's sufficient as prevention for the hanging and programmer doesn't need to check if wl_display_prepare_read (that was previously covered by this patch too) returned an error or the queue just was not empty. Without the check, it could result in indefinite looping. Thanks to Pekka Paalanen <pekka.paala...@collabora.co.uk> for constant reviewing and discussing this patch. Signed-off-by: Marek Chalupa <mchqwe...@gmail.com> Reviewed-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> diff --git a/src/wayland-client.c b/src/wayland-client.c index 0f3f3d9..9159ee0 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -1200,6 +1200,13 @@ wl_display_read_events(struct wl_display *display) pthread_mutex_lock(&display->mutex); + if (display->last_error) { + pthread_mutex_unlock(&display->mutex); + + errno = display->last_error; + return -1; + } + ret = read_events(display); pthread_mutex_unlock(&display->mutex); commit 574b710ef8da766019a406801893937a6df9357c Author: Marek Chalupa <mchqwe...@gmail.com> Date: Tue Aug 5 11:42:01 2014 +0200 client: broadcast the right pthread_cond variable In previous commit we removed unused variables. One of them was pthread_cond_t that was formerly used when reading from display, but later was (erroneously) made unused. This patch fixes this error and is a fix for the failing test introduced few patches ago (tests: test if thread can block on error) Reviewed-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> diff --git a/src/wayland-client.c b/src/wayland-client.c index 4b184d5..0f3f3d9 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -127,6 +127,12 @@ display_fatal_error(struct wl_display *display, int error) error = EFAULT; display->last_error = error; + + pthread_cond_broadcast(&display->reader_cond); + /* prevent from indefinite looping in read_events() + * (when calling pthread_cond_wait under condition + * display->read_serial == serial) */ + ++display->read_serial; } /** @@ -175,6 +181,16 @@ display_protocol_error(struct wl_display *display, uint32_t code, display->protocol_error.id = id; display->protocol_error.interface = intf; + /* + * here it is not necessary to broadcast reader's cond like in + * display_fatal_error, because this function is called from + * an event handler and that means that read_events() is done + * and woke up all threads. Since wl_display_prepare_read() + * fails when there are events in the queue, no threads + * can sleep in read_events() during dispatching + * (and therefore during calling this function), so this is safe. + */ + pthread_mutex_unlock(&display->mutex); } commit 0cb9862c938f754dbda5394c56ac09dae3a20201 Author: Olivier Blin <olivier.b...@softathome.com> Date: Thu Aug 21 16:54:21 2014 +0200 client: drop unused event queue cond and list variables The wl_event_queue cond variable has been replaced by the wl_display reader_cond variable (commit 3c7e8bfbb4745315b7bcbf69fa746c3d6718c305). This cond variable is never waited for anymore, just signaled/broadcasted, and thus can be safely removed. The wl_display event_queue_list and link from wl_event_queue can be removed as well, since it was only used to iterate over the event queue list in order to broadcast the now unused cond. No regression on queue unit tests. Signed-off-by: Olivier Blin <olivier.b...@softathome.com> v2: fixed and rebased after 886b09c9a3a9d8672039f09fe7eaf3f2b2b012ca added signed-off-by v3: removed link from wl_event_queue Signed-off-by: Marek Chalupa <mchqwe...@gmail.com> Reviewed-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> diff --git a/src/wayland-client.c b/src/wayland-client.c index 2252424..4b184d5 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -69,10 +69,8 @@ struct wl_global { }; struct wl_event_queue { - struct wl_list link; struct wl_list event_list; struct wl_display *display; - pthread_cond_t cond; }; struct wl_display { @@ -100,7 +98,6 @@ struct wl_display { struct wl_map objects; struct wl_event_queue display_queue; struct wl_event_queue default_queue; - struct wl_list event_queue_list; pthread_mutex_t mutex; int reader_count; @@ -123,8 +120,6 @@ static int debug_client = 0; static void display_fatal_error(struct wl_display *display, int error) { - struct wl_event_queue *iter; - if (display->last_error) return; @@ -132,9 +127,6 @@ display_fatal_error(struct wl_display *display, int error) error = EFAULT; display->last_error = error; - - wl_list_for_each(iter, &display->event_queue_list, link) - pthread_cond_broadcast(&iter->cond); } /** @@ -153,7 +145,6 @@ static void display_protocol_error(struct wl_display *display, uint32_t code, uint32_t id, const struct wl_interface *intf) { - struct wl_event_queue *iter; int err; if (display->last_error) @@ -184,9 +175,6 @@ display_protocol_error(struct wl_display *display, uint32_t code, display->protocol_error.id = id; display->protocol_error.interface = intf; - wl_list_for_each(iter, &display->event_queue_list, link) - pthread_cond_broadcast(&iter->cond); - pthread_mutex_unlock(&display->mutex); } @@ -194,7 +182,6 @@ static void wl_event_queue_init(struct wl_event_queue *queue, struct wl_display *display) { wl_list_init(&queue->event_list); - pthread_cond_init(&queue->cond, NULL); queue->display = display; } @@ -209,7 +196,6 @@ wl_event_queue_release(struct wl_event_queue *queue) wl_list_remove(&closure->link); wl_closure_destroy(closure); } - pthread_cond_destroy(&queue->cond); } /** Destroy an event queue @@ -231,7 +217,6 @@ wl_event_queue_destroy(struct wl_event_queue *queue) struct wl_display *display = queue->display; pthread_mutex_lock(&display->mutex); - wl_list_remove(&queue->link); wl_event_queue_release(queue); free(queue); pthread_mutex_unlock(&display->mutex); @@ -256,10 +241,6 @@ wl_display_create_queue(struct wl_display *display) wl_event_queue_init(queue, display); - pthread_mutex_lock(&display->mutex); - wl_list_insert(&display->event_queue_list, &queue->link); - pthread_mutex_unlock(&display->mutex); - return queue; } @@ -767,7 +748,6 @@ wl_display_connect_to_fd(int fd) wl_map_init(&display->objects, WL_MAP_CLIENT_SIDE); wl_event_queue_init(&display->default_queue, display); wl_event_queue_init(&display->display_queue, display); - wl_list_init(&display->event_queue_list); pthread_mutex_init(&display->mutex, NULL); pthread_cond_init(&display->reader_cond, NULL); display->reader_count = 0; @@ -1046,8 +1026,6 @@ queue_event(struct wl_display *display, int len) else queue = proxy->queue; - if (wl_list_empty(&queue->event_list)) - pthread_cond_signal(&queue->cond); wl_list_insert(queue->event_list.prev, &closure->link); return size; commit 71141288f0aaf7df9d06469d4a0ee21d7384243b Author: Marek Chalupa <mchqwe...@gmail.com> Date: Tue Aug 5 11:39:51 2014 +0200 tests: add test for reading after an error occurred This test shows that it's possible to successfully call wl_display_prepare_read and wl_display_read_events after an error occurred. That may lead to deadlock. When you call prepare read from two threads and then call read_events, one thread gets sleeping. The call from the other thread will return -1 and invokes display_fatal_error, but since we have display->last_error already set, the broadcast is not called and the sleeping thread sleeps indefinitely. Reviewed-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> diff --git a/tests/display-test.c b/tests/display-test.c index 28ef40b..c420cbe 100644 --- a/tests/display-test.c +++ b/tests/display-test.c @@ -482,3 +482,63 @@ TEST(threading_cancel_read_tst) display_destroy(d); } + +static void * +thread_prepare_and_read2(void *data) +{ + struct client *c = data; + + while(wl_display_prepare_read(c->wl_display) != 0 && errno == EAGAIN) + assert(wl_display_dispatch_pending(c->wl_display) == -1); + assert(wl_display_flush(c->wl_display) == -1); + + c->display_stopped = 1; + + assert(wl_display_read_events(c->wl_display) == -1); + assert(wl_display_dispatch_pending(c->wl_display) == -1); + + pthread_exit(NULL); +} + +static void +threading_read_after_error(void) +{ + struct client *c = client_connect(); + pthread_t thread; + + /* create an error */ + close(wl_display_get_fd(c->wl_display)); + assert(wl_display_dispatch(c->wl_display) == -1); + + /* try to prepare for reading */ + while(wl_display_prepare_read(c->wl_display) != 0 && errno == EAGAIN) + assert(wl_display_dispatch_pending(c->wl_display) == -1); + assert(wl_display_flush(c->wl_display) == -1); + + assert(pthread_create(&thread, NULL, + thread_prepare_and_read2, c) == 0); + + /* make sure thread is sleeping */ + while (c->display_stopped == 0) + usleep(500); + usleep(10000); + + assert(wl_display_read_events(c->wl_display) == -1); + + /* kill test in 3 seconds */ + alarm(3); + pthread_join(thread, NULL); + + wl_proxy_destroy((struct wl_proxy *) c->tc); + wl_display_disconnect(c->wl_display); +} + +TEST(threading_read_after_error_tst) +{ + struct display *d = display_create(); + + client_create(d, threading_read_after_error); + display_run(d); + + display_destroy(d); +} commit 213366e698fedf0caac0e7a0bf2f05e2446ba113 Author: Marek Chalupa <mchqwe...@gmail.com> Date: Tue Aug 5 11:39:50 2014 +0200 tests: add tests for wl_display_cancel_read Test if wl_display_cancel_read wakes up other threads. Reviewed-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> diff --git a/tests/display-test.c b/tests/display-test.c index 26f946b..28ef40b 100644 --- a/tests/display-test.c +++ b/tests/display-test.c @@ -413,3 +413,72 @@ TEST(threading_errors_tst) display_destroy(d); } + +static void * +thread_prepare_and_read(void *data) +{ + struct client *c = data; + + register_reading(c->wl_display); + + c->display_stopped = 1; + + assert(wl_display_read_events(c->wl_display) == 0); + assert(wl_display_dispatch_pending(c->wl_display) == 0); + + pthread_exit(NULL); +} + +static pthread_t +create_thread(struct client *c) +{ + pthread_t thread; + + c->display_stopped = 0; + assert(pthread_create(&thread, NULL, thread_prepare_and_read, c) == 0); + + /* make sure thread is sleeping */ + while (c->display_stopped == 0) + usleep(500); + usleep(10000); + + return thread; +} + +/* test cancel read*/ +static void +threading_cancel_read(void) +{ + struct client *c = client_connect(); + pthread_t th1, th2, th3; + + register_reading(c->wl_display); + + th1 = create_thread(c); + th2 = create_thread(c); + th3 = create_thread(c); + + /* all the threads are sleeping, waiting until read or cancel + * is called. Cancel the read and let the threads proceed */ + wl_display_cancel_read(c->wl_display); + + /* kill test in 3 seconds. This should be enough time for the + * thread to exit if it's not blocking. If everything is OK, than + * the thread was woken up and the test will end before the SIGALRM */ + alarm(3); + pthread_join(th1, NULL); + pthread_join(th2, NULL); + pthread_join(th3, NULL); + + client_disconnect(c); +} + +TEST(threading_cancel_read_tst) +{ + struct display *d = display_create(); + + client_create(d, threading_cancel_read); + display_run(d); + + display_destroy(d); +} commit 171e0bdace16dca6d532494a076f0970cb8a034c Author: Marek Chalupa <mchqwe...@gmail.com> Date: Tue Aug 5 11:39:49 2014 +0200 tests: test if thread can block on error wl_display_read_events() can make a thread wait until some other thread ends reading. Normally it wakes up all threads after the reading is done. But there's a place when it does not get to waking up the threads - when an error occurs. This test reveals bug that can block programs. If a thread is waiting in wl_display_read_events() and another thread calls wl_display_read_events and the reading fails, then the sleeping thread is not woken up. This is because display_handle_error is using old pthread_cond instead of new display->reader_cond, that was added along with wl_display_read_events(). Reviewed-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> diff --git a/tests/display-test.c b/tests/display-test.c index e212942..26f946b 100644 --- a/tests/display-test.c +++ b/tests/display-test.c @@ -31,6 +31,7 @@ #include <errno.h> #include <sys/types.h> #include <sys/stat.h> +#include <pthread.h> #include "wayland-private.h" #include "wayland-server.h" @@ -323,3 +324,92 @@ TEST(post_nomem_tst) display_destroy(d); } + +static void +register_reading(struct wl_display *display) +{ + while(wl_display_prepare_read(display) != 0 && errno == EAGAIN) + assert(wl_display_dispatch_pending(display) >= 0); + assert(wl_display_flush(display) >= 0); +} + +static void * +thread_read_error(void *data) +{ + struct client *c = data; + + register_reading(c->wl_display); + + /* + * Calling the read right now will block this thread + * until the other thread will read the data. + * However, after invoking an error, this + * thread should be woken up or it will block indefinitely. + */ + c->display_stopped = 1; + assert(wl_display_read_events(c->wl_display) == 0); + + wl_display_dispatch_pending(c->wl_display); + assert(wl_display_get_error(c->wl_display)); + + pthread_exit(NULL); +} + +/* test posting an error in multi-threaded environment. */ +static void +threading_post_err(void) +{ + struct client *c = client_connect(); + pthread_t thread; + + /* register read intention */ + register_reading(c->wl_display); + + /* use this var as an indicator that thread is sleeping */ + c->display_stopped = 0; + + /* create new thread that will register its intention too */ + assert(pthread_create(&thread, NULL, thread_read_error, c) == 0); + + /* make sure thread is sleeping. It's a little bit racy + * (setting display_stopped to 1 and calling wl_display_read_events) + * so call usleep once again after the loop ends - it should + * be sufficient... */ + while (c->display_stopped == 0) + usleep(500); + + usleep(10000); + + /* so now we have sleeping thread waiting for a pthread_cond signal. + * The main thread must call wl_display_read_events(). + * If this call fails, then it won't call broadcast at the + * end of the function and the sleeping thread will block indefinitely. + * Make the call fail and watch if libwayland will unblock the thread! */ + + /* create error on fd, so that wl_display_read_events will fail. + * The same can happen when server hangs up */ + close(wl_display_get_fd(c->wl_display)); + /* this read events will fail and will + * post an error that should wake the sleeping thread + * and dispatch the incoming events */ + assert(wl_display_read_events(c->wl_display) == -1); + + /* kill test in 3 seconds. This should be enough time for the + * thread to exit if it's not blocking. If everything is OK, than + * the thread was woken up and the test will end before the SIGALRM */ + alarm(3); + pthread_join(thread, NULL); + + wl_proxy_destroy((struct wl_proxy *) c->tc); + wl_display_disconnect(c->wl_display); +} + +TEST(threading_errors_tst) +{ + struct display *d = display_create(); + + client_create(d, threading_post_err); + display_run(d); + + display_destroy(d); +} commit 47208d2ab12c7671e1b8dc80c4d15094f0b310f7 Author: Marek Chalupa <mchqwe...@gmail.com> Date: Mon May 26 17:04:23 2014 +0200 tests: test posting errors Test posting errors to one and more clients. Reviewed-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> diff --git a/tests/display-test.c b/tests/display-test.c index 844a649..e212942 100644 --- a/tests/display-test.c +++ b/tests/display-test.c @@ -34,7 +34,9 @@ #include "wayland-private.h" #include "wayland-server.h" +#include "wayland-client.h" #include "test-runner.h" +#include "test-compositor.h" struct display_destroy_listener { struct wl_listener listener; @@ -77,3 +79,247 @@ TEST(display_destroy_listener) assert(b.done); } +static void +registry_handle_globals(void *data, struct wl_registry *registry, + uint32_t id, const char *intf, uint32_t ver) +{ + struct wl_seat **seat = data; + + if (strcmp(intf, "wl_seat") == 0) { + *seat = wl_registry_bind(registry, id, + &wl_seat_interface, ver); + assert(*seat); + } +} + +static const struct wl_registry_listener registry_listener = { + registry_handle_globals, + NULL +}; + +static struct wl_seat * +client_get_seat(struct client *c) +{ + struct wl_seat *seat; + struct wl_registry *reg = wl_display_get_registry(c->wl_display); + assert(reg); + + wl_registry_add_listener(reg, ®istry_listener, &seat); + wl_display_roundtrip(c->wl_display); + assert(seat); + + wl_registry_destroy(reg); + + return seat; +} + +static void +check_for_error(struct client *c, struct wl_proxy *proxy) +{ + uint32_t ec, id; + int err; + const struct wl_interface *intf; + + /* client should be disconnected */ + assert(wl_display_roundtrip(c->wl_display) == -1); + + err = wl_display_get_error(c->wl_display); + assert(err == EPROTO); + + ec = wl_display_get_protocol_error(c->wl_display, &intf, &id); + assert(ec == 23); + assert(intf == &wl_seat_interface); + assert(id == wl_proxy_get_id(proxy)); +} + +static void +bind_seat(struct wl_client *client, void *data, + uint32_t vers, uint32_t id) +{ + struct display *d = data; + struct client_info *ci; + struct wl_resource *res; + + /* find the right client_info struct and save the + * resource as its data, so that we can use it later */ + wl_list_for_each(ci, &d->clients, link) { + if (ci->wl_client == client) + break; + } + + res = wl_resource_create(client, &wl_seat_interface, vers, id); + assert(res); + + ci->data = res; +} + +static void +post_error_main(void) +{ + struct client *c = client_connect(); + struct wl_seat *seat = client_get_seat(c); + + /* stop display so that it can post the error. + * The function should return -1, because of the posted error */ + assert(stop_display(c, 1) == -1); + + /* display should have posted error, check it! */ + check_for_error(c, (struct wl_proxy *) seat); + + /* don't call client_disconnect(c), because then the test would be + * aborted due to checks for error in this function */ + wl_proxy_destroy((struct wl_proxy *) seat); + wl_proxy_destroy((struct wl_proxy *) c->tc); + wl_display_disconnect(c->wl_display); +} + +TEST(post_error_to_one_client) +{ + struct display *d = display_create(); + struct client_info *cl; + + wl_global_create(d->wl_display, &wl_seat_interface, + 1, d, bind_seat); + + cl = client_create(d, post_error_main); + display_run(d); + + /* the display was stopped by client, so it can + * proceed in the code and post an error */ + assert(cl->data); + wl_resource_post_error((struct wl_resource *) cl->data, + 23, "Dummy error"); + + /* this one should be ignored */ + wl_resource_post_error((struct wl_resource *) cl->data, + 21, "Dummy error (ignore)"); + + display_resume(d); + display_destroy(d); +} + +static void +post_error_main2(void) +{ + struct client *c = client_connect(); + struct wl_seat *seat = client_get_seat(c); + + /* the error should not be posted for this client */ + assert(stop_display(c, 2) >= 0); + + wl_proxy_destroy((struct wl_proxy *) seat); + client_disconnect(c); +} + +static void +post_error_main3(void) +{ + struct client *c = client_connect(); + struct wl_seat *seat = client_get_seat(c); + + assert(stop_display(c, 2) == -1); + check_for_error(c, (struct wl_proxy *) seat); + + /* don't call client_disconnect(c), because then the test would be + * aborted due to checks for error in this function */ + wl_proxy_destroy((struct wl_proxy *) seat); + wl_proxy_destroy((struct wl_proxy *) c->tc); + wl_display_disconnect(c->wl_display); +} + +/* all the testcases could be in one TEST, but splitting it + * apart is better for debugging when the test fails */ +TEST(post_error_to_one_from_two_clients) +{ + struct display *d = display_create(); + struct client_info *cl; + + wl_global_create(d->wl_display, &wl_seat_interface, + 1, d, bind_seat); + + client_create(d, post_error_main2); + cl = client_create(d, post_error_main3); + display_run(d); + + /* post error only to the second client */ + assert(cl->data); + wl_resource_post_error((struct wl_resource *) cl->data, + 23, "Dummy error"); + wl_resource_post_error((struct wl_resource *) cl->data, + 21, "Dummy error (ignore)"); + + display_resume(d); + display_destroy(d); +} + +/* all the testcases could be in one TEST, but splitting it + * apart is better for debugging when the test fails */ +TEST(post_error_to_two_clients) +{ + struct display *d = display_create(); + struct client_info *cl, *cl2; + + wl_global_create(d->wl_display, &wl_seat_interface, + 1, d, bind_seat); + + cl = client_create(d, post_error_main3); + cl2 = client_create(d, post_error_main3); + + display_run(d); + + /* Try to send the error to both clients */ + assert(cl->data && cl2->data); + wl_resource_post_error((struct wl_resource *) cl->data, + 23, "Dummy error"); + wl_resource_post_error((struct wl_resource *) cl->data, + 21, "Dummy error (ignore)"); + + wl_resource_post_error((struct wl_resource *) cl2->data, + 23, "Dummy error"); + wl_resource_post_error((struct wl_resource *) cl2->data, + 21, "Dummy error (ignore)"); + + display_resume(d); + display_destroy(d); +} + +static void +post_nomem_main(void) +{ + struct client *c = client_connect(); + struct wl_seat *seat = client_get_seat(c); + + assert(stop_display(c, 1) == -1); + assert(wl_display_get_error(c->wl_display) == ENOMEM); + + wl_proxy_destroy((struct wl_proxy *) seat); + wl_proxy_destroy((struct wl_proxy *) c->tc); + wl_display_disconnect(c->wl_display); +} + +TEST(post_nomem_tst) +{ + struct display *d = display_create(); + struct client_info *cl; + + wl_global_create(d->wl_display, &wl_seat_interface, + 1, d, bind_seat); + + cl = client_create(d, post_nomem_main); + display_run(d); + + assert(cl->data); + wl_resource_post_no_memory((struct wl_resource *) cl->data); + display_resume(d); + + /* first client terminated. Run it again, + * but post no memory to client */ + cl = client_create(d, post_nomem_main); + display_run(d); + + assert(cl->data); + wl_client_post_no_memory(cl->wl_client); + display_resume(d); + + display_destroy(d); +} commit 93e654061b9497c78b6f89a0b7f54107029e2628 Author: Marek Chalupa <mchqwe...@gmail.com> Date: Thu Aug 21 16:53:14 2014 +0200 tests: use test compositor in queue-test Most of the code of the queue-test is covered by the test compositor, so we can save few lines and use the test compositor instead. I think it's also more readable. This patch removes timeout from the test. We plan to add timeout to all tests later, though. v2. rebased to master Signed-off-by: Marek Chalupa <mchqwe...@gmail.com> Reviewed-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> diff --git a/tests/queue-test.c b/tests/queue-test.c index a7b54d9..96f2100 100644 --- a/tests/queue-test.c +++ b/tests/queue-test.c @@ -31,33 +31,17 @@ #include "wayland-client.h" #include "wayland-server.h" -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: https://lists.debian.org/e1xpi7l-0002kd...@moszumanska.debian.org