On Wed, 25 Jun 2014 14:35:16 +0200 Marek Chalupa <mchqwe...@gmail.com> wrote:
> Test if events are going to the right queue and if the queue > is interrupted from polling when an error to the main queue comes. > The last one is failing. > --- > tests/queue-test.c | 128 > +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 128 insertions(+) > > diff --git a/tests/queue-test.c b/tests/queue-test.c > index 36d7a69..307bae9 100644 > --- a/tests/queue-test.c > +++ b/tests/queue-test.c > @@ -27,6 +27,7 @@ > #include <sys/types.h> > #include <sys/wait.h> > #include <assert.h> > +#include <pthread.h> > > #include "wayland-client.h" > #include "wayland-server.h" > @@ -139,6 +140,53 @@ client_test_multiple_queues(void) > exit(ret == -1 ? -1 : 0); > } > > +/* test that events will come to the right queue */ > +static void > +client_test_multiple_queues2(void) > +{ > + struct wl_event_queue *queue[5], *q; Instead of using 5 everwhere, how about a #define? > + struct wl_callback *callback; > + struct wl_display *display; > + int i, j; > + > + display = wl_display_connect(NULL); > + assert(display); > + > + for (i = 0; i < 5; ++i) { > + queue[i] = wl_display_create_queue(display); > + assert(queue[i]); > + } > + > + for (i = 0; i < 100; ++i) { > + q = queue[i % 5]; > + callback = wl_display_sync(display); Isn't this 'callback' leaked? > + assert(callback != NULL); > + wl_proxy_set_queue((struct wl_proxy *) callback, q); > + > + assert(wl_display_flush(display) > 0); > + > + /* the callback should come to the q queue */ > + assert(wl_display_dispatch_pending(display) == 0); > + assert(wl_display_dispatch_queue(display, q) > 0); > + /* now all queues should be empty */ > + for (j = 0; j < 5; ++j) > + assert(wl_display_dispatch_queue_pending(display, > + queue[j]) == > 0); > + } > + > + callback = wl_display_sync(display); And this? > + assert(callback != NULL); > + > + assert(wl_display_flush(display) > 0); > + assert(wl_display_dispatch(display) > 0); > + for (j = 0; j < 5; ++j) { > + assert(wl_display_dispatch_queue_pending(display, queue[j]) == > 0); > + wl_event_queue_destroy(queue[j]); > + } > + > + wl_display_disconnect(display); > +} > + > static void > dummy_bind(struct wl_client *client, > void *data, uint32_t version, uint32_t id) > @@ -169,5 +217,85 @@ TEST(queue) > client_create(d, client_test_multiple_queues); > display_run(d); > > + client_create(d, client_test_multiple_queues2); > + display_run(d); > + > + display_destroy(d); > +} > + > +struct thread_data { > + struct wl_display *display; > + struct wl_event_queue *queue; > +}; > + > +static void * > +run_new_queue(void *arg) > +{ > + struct thread_data *data = arg; > + int ret; > + > + /* XXX shouldn't it return -1 in the first dispatch? > + * Anyway - the queue keeps polling atm and is not interrupted by > + * the error */ Hmm, yes, I think would probably be good that if wl_display goes into error state, all the dispatch calls should return with error, rather than hang. > + do { > + ret = wl_display_dispatch_queue(data->display, data->queue); > + /* it definitely cannot dispatch any event */ > + assert(ret <= 0); > + } while (ret != -1); > + > + pthread_exit(NULL); > +} > + > +static void > +client_test_multiple_queues_errors(void) > +{ > + struct client *c; > + struct wl_event_queue *queue; > + struct thread_data data; > + pthread_t thr; > + > + c = client_connect(); > + > + queue = wl_display_create_queue(c->wl_display); > + assert(queue); > + > + data.display = c->wl_display; > + data.queue = queue; > + /* run new thread that will wait for event in > + * the new queue. Then post an error and check > + * if the dispatching was cancelled... */ > + assert(pthread_create(&thr, NULL, run_new_queue, &data) == 0); > + > + stop_display(c, 1); > + > + /* make sure we got the error */ > + alarm(3); /* timeout */ > + wl_display_roundtrip(c->wl_display); > + assert(wl_display_get_error(c->wl_display) != 0); > + > + /* wait for the thread to finish */ > + assert(pthread_join(thr, NULL) == 0); > + > + /* do not use client_disconnect(c), because it would > + * fail the test since we posted an error */ > + wl_event_queue_destroy(queue); > + wl_proxy_destroy((struct wl_proxy *) c->tc); > + wl_display_disconnect(c->wl_display); > +} > + > +TEST(queue_errors) > +{ > + struct display *d = display_create(); > + > + client_create(d, client_test_multiple_queues_errors); > + display_run(d); > + > + /* get the client */ > + struct client_info *ci = wl_container_of(d->clients.next, ci, link); > + assert(ci && ci->wl_client != NULL); > + > + wl_client_post_no_memory(ci->wl_client); > + display_resume(d); > + > display_destroy(d); > } Very nice work! :-) Thanks, pq _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel