Re: [PATCH] tests: add multiple-queues testcases

2014-08-22 Thread Marek Chalupa
On 21 August 2014 15:15, Pekka Paalanen ppaala...@gmail.com wrote:

 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?


Yes, that'll be better.



  + 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?


I'll add a listener that will destroy the callbacks.






 + 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.


Actually, this test-case is wrong. When I was writing this, I did not know
anything about threading in Wayland.
Nowadays, I know that this is exactly the case where
wl_display_prepare_read + wl_display_read_events should
be used (more threads are reading from the display's fd), so when
programmer will do what is in this test,
it is his fault. However, I think I could send a path that clarifies this
in the documentation
(I've already sent one, but that is only for wl_display_prepare_read and
there's no note about not using wl_display_dispatch concurrently:
http://lists.freedesktop.org/archives/wayland-devel/2014-August/016296.html)

However, this test-case shows that it is possible to have one thread
polling and the other successfully dispatching events
without interrupting the poll, so I'll try to find out if it can happen in
some correct way.



  + 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;
  +  

Re: [PATCH] tests: add multiple-queues testcases

2014-08-22 Thread Pekka Paalanen
On Fri, 22 Aug 2014 09:42:16 +0200
Marek Chalupa mchqwe...@gmail.com wrote:

 On 21 August 2014 15:15, Pekka Paalanen ppaala...@gmail.com wrote:
 
  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?
 
 
 Yes, that'll be better.
 
 
 
   + 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?
 
 
 I'll add a listener that will destroy the callbacks.
 
 
 
 
 
 
  + 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.
 
 
 Actually, this test-case is wrong. When I was writing this, I did not know
 anything about threading in Wayland.
 Nowadays, I know that this is exactly the case where
 wl_display_prepare_read + wl_display_read_events should
 be used (more threads are reading from the display's fd), so when
 programmer will do what is in this test,
 it is his fault. However, I think I could send a path that clarifies this
 in the documentation
 (I've already sent one, but that is only for wl_display_prepare_read and
 there's no note about not using wl_display_dispatch concurrently:
 http://lists.freedesktop.org/archives/wayland-devel/2014-August/016296.html)
 
 However, this test-case shows that it is possible to have one thread
 polling and the other successfully dispatching events
 without interrupting the poll, so I'll try to find out if it can happen in
 some correct way.

Oh, ok. So this test as it was written, was also incorrect with the API
that was before wl_display_prepare_read?

I don't think that old API was ever removed, nor can be removed, so it
should still work according to the old rules. To make things even more
complicated, I suppose it should still work, if, say, an app is using
the older API and a library is using the latest 

Re: [PATCH] tests: add multiple-queues testcases

2014-08-22 Thread Marek Chalupa
On 22 August 2014 11:50, Pekka Paalanen ppaala...@gmail.com wrote:

 On Fri, 22 Aug 2014 09:42:16 +0200
 Marek Chalupa mchqwe...@gmail.com wrote:

  On 21 August 2014 15:15, Pekka Paalanen ppaala...@gmail.com wrote:
 
   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?
  
 
  Yes, that'll be better.
 
 
  
+ 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?
  
 
  I'll add a listener that will destroy the callbacks.
 
 
  
  
 
  
   + 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.
  
  
  Actually, this test-case is wrong. When I was writing this, I did not
 know
  anything about threading in Wayland.
  Nowadays, I know that this is exactly the case where
  wl_display_prepare_read + wl_display_read_events should
  be used (more threads are reading from the display's fd), so when
  programmer will do what is in this test,
  it is his fault. However, I think I could send a path that clarifies this
  in the documentation
  (I've already sent one, but that is only for wl_display_prepare_read and
  there's no note about not using wl_display_dispatch concurrently:
 
 http://lists.freedesktop.org/archives/wayland-devel/2014-August/016296.html
 )
 
  However, this test-case shows that it is possible to have one thread
  polling and the other successfully dispatching events
  without interrupting the poll, so I'll try to find out if it can happen
 in
  some correct way.

 Oh, ok. So this test as it was written, was also incorrect with the API
 that was before wl_display_prepare_read?


Hmm, not exactly. AFAIK, before wl_display_prepare_read only the main thread
was allowed to read from fd and dispatch 

Re: [PATCH] tests: add multiple-queues testcases

2014-08-21 Thread Pekka Paalanen
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);
 +
 + 

[PATCH] tests: add multiple-queues testcases

2014-06-25 Thread Marek Chalupa
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;
+   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);
+   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);
+   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 */
+   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);
 }
-- 
1.9.3

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH] tests: add multiple-queues testcases

2014-06-25 Thread Marek Chalupa
I meant to send it in reply-to
http://lists.freedesktop.org/archives/wayland-devel/2014-June/015627.html
and http://lists.freedesktop.org/archives/wayland-devel/2014-May/015098.html

Regards,
Marek


On 25 June 2014 14:35, 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;
 +   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);
 +   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);
 +   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 */
 +   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 =