diff options
Diffstat (limited to 'tests/event-loop-test.c')
| -rw-r--r-- | tests/event-loop-test.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/tests/event-loop-test.c b/tests/event-loop-test.c index f250ed0..1218163 100644 --- a/tests/event-loop-test.c +++ b/tests/event-loop-test.c @@ -25,6 +25,7 @@ #include <assert.h> #include <unistd.h> #include <signal.h> +#include <sys/time.h> #include "wayland-private.h" #include "wayland-server.h" @@ -199,6 +200,79 @@ TEST(event_loop_timer) wl_event_loop_destroy(loop); } +struct timer_update_context { + struct wl_event_source *source1, *source2; + int count; +}; + +static int +timer_update_callback_1(void *data) +{ + struct timer_update_context *context = data; + + context->count++; + wl_event_source_timer_update(context->source2, 1000); + return 1; +} + +static int +timer_update_callback_2(void *data) +{ + struct timer_update_context *context = data; + + context->count++; + wl_event_source_timer_update(context->source1, 1000); + return 1; +} + +TEST(event_loop_timer_updates) +{ + struct wl_event_loop *loop = wl_event_loop_create(); + struct wl_event_source *source; + struct timer_update_context context; + struct timeval start_time, end_time, interval; + + /* Create two timers that should expire at the same time (after 10ms). + * The first timer to receive its expiry callback updates the other timer + * with a much larger timeout (1s). This highlights a bug where + * wl_event_source_timer_dispatch would block for this larger timeout + * when reading from the timer fd, before calling the second timer's + * callback. + */ + + context.source1 = wl_event_loop_add_timer(loop, timer_update_callback_1, + &context); + assert(context.source1); + wl_event_source_timer_update(context.source1, 10); + + context.source2 = wl_event_loop_add_timer(loop, timer_update_callback_2, + &context); + assert(context.source2); + wl_event_source_timer_update(context.source2, 10); + + context.count = 0; + + gettimeofday(&start_time, NULL); + wl_event_loop_dispatch(loop, 20); + gettimeofday(&end_time, NULL); + + assert(context.count == 2); + + /* Dispatching the events should not have taken much more than 20ms, + * since this is the timeout passed to wl_event_loop_dispatch. If it + * blocked, then it will have taken over 1s. + * Of course, it could take over 1s anyway on a very slow or heavily + * loaded system, so this test isn't 100% perfect. + */ + + timersub(&end_time, &start_time, &interval); + assert(interval.tv_sec < 1); + + wl_event_source_remove(context.source1); + wl_event_source_remove(context.source2); + wl_event_loop_destroy(loop); +} + struct event_loop_destroy_listener { struct wl_listener listener; int done; |
