diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2012-03-21 10:29:47 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-03-21 10:30:19 -0400 |
commit | f48bd0714a9b77935fab679a7f03bb26b309e82b (patch) | |
tree | e512074cb3e578419e55a504202e071e9b38a01a /tests | |
parent | 81ffaa04b9c17f868844294aa107155f397650f2 (diff) |
tests: Add test case for freeing source with pending data
Diffstat (limited to 'tests')
-rw-r--r-- | tests/event-loop-test.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/tests/event-loop-test.c b/tests/event-loop-test.c index 5570f90..b1dc3f6 100644 --- a/tests/event-loop-test.c +++ b/tests/event-loop-test.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include <assert.h> +#include <unistd.h> #include "../src/wayland-server.h" #include "test-runner.h" @@ -51,3 +52,72 @@ TEST(post_dispatch_check) wl_event_source_remove(source); wl_event_loop_destroy(loop); } + +struct free_source_context { + struct wl_event_source *source1, *source2; + int p1[2], p2[2]; + int count; +}; + +static int +free_source_callback(int fd, uint32_t mask, void *data) +{ + struct free_source_context *context = data; + + context->count++; + + /* Remove other source */ + if (fd == context->p1[0]) { + wl_event_source_remove(context->source2); + context->source2 = NULL; + } else if (fd == context->p2[0]) { + wl_event_source_remove(context->source1); + context->source1 = NULL; + } else { + assert(0); + } + + return 1; +} + +TEST(free_source_with_data) +{ + struct wl_event_loop *loop = wl_event_loop_create(); + struct free_source_context context; + int data; + + /* This test is a little tricky to get right, since we don't + * have any guarantee from the event loop (ie epoll) on the + * order of which it reports events. We want to have one + * source free the other, but we don't know which one is going + * to run first. So we add two fd sources with a callback + * that frees the other source and check that only one of them + * run (and that we don't crash, of course). + */ + + context.count = 0; + assert(pipe(context.p1) == 0); + assert(pipe(context.p2) == 0); + context.source1 = + wl_event_loop_add_fd(loop, context.p1[0], WL_EVENT_READABLE, + free_source_callback, &context); + assert(context.source1); + context.source2 = + wl_event_loop_add_fd(loop, context.p2[0], WL_EVENT_READABLE, + free_source_callback, &context); + assert(context.source2); + + data = 5; + assert(write(context.p1[1], &data, sizeof data) == sizeof data); + assert(write(context.p2[1], &data, sizeof data) == sizeof data); + + wl_event_loop_dispatch(loop, 0); + + assert(context.count == 1); + + if (context.source1) + wl_event_source_remove(context.source1); + if (context.source2) + wl_event_source_remove(context.source2); + wl_event_loop_destroy(loop); +} |