1818c5d8cc721053be659c92b577217914905883Lloyd Pique/* 2818c5d8cc721053be659c92b577217914905883Lloyd Pique * Copyright © 2012 Intel Corporation 3818c5d8cc721053be659c92b577217914905883Lloyd Pique * Copyright © 2012 Jason Ekstrand 4818c5d8cc721053be659c92b577217914905883Lloyd Pique * 5818c5d8cc721053be659c92b577217914905883Lloyd Pique * Permission is hereby granted, free of charge, to any person obtaining 6818c5d8cc721053be659c92b577217914905883Lloyd Pique * a copy of this software and associated documentation files (the 7818c5d8cc721053be659c92b577217914905883Lloyd Pique * "Software"), to deal in the Software without restriction, including 8818c5d8cc721053be659c92b577217914905883Lloyd Pique * without limitation the rights to use, copy, modify, merge, publish, 9818c5d8cc721053be659c92b577217914905883Lloyd Pique * distribute, sublicense, and/or sell copies of the Software, and to 10818c5d8cc721053be659c92b577217914905883Lloyd Pique * permit persons to whom the Software is furnished to do so, subject to 11818c5d8cc721053be659c92b577217914905883Lloyd Pique * the following conditions: 12818c5d8cc721053be659c92b577217914905883Lloyd Pique * 13818c5d8cc721053be659c92b577217914905883Lloyd Pique * The above copyright notice and this permission notice (including the 14818c5d8cc721053be659c92b577217914905883Lloyd Pique * next paragraph) shall be included in all copies or substantial 15818c5d8cc721053be659c92b577217914905883Lloyd Pique * portions of the Software. 16818c5d8cc721053be659c92b577217914905883Lloyd Pique * 17818c5d8cc721053be659c92b577217914905883Lloyd Pique * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18818c5d8cc721053be659c92b577217914905883Lloyd Pique * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19818c5d8cc721053be659c92b577217914905883Lloyd Pique * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20818c5d8cc721053be659c92b577217914905883Lloyd Pique * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21818c5d8cc721053be659c92b577217914905883Lloyd Pique * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22818c5d8cc721053be659c92b577217914905883Lloyd Pique * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23818c5d8cc721053be659c92b577217914905883Lloyd Pique * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24818c5d8cc721053be659c92b577217914905883Lloyd Pique * SOFTWARE. 25818c5d8cc721053be659c92b577217914905883Lloyd Pique */ 26818c5d8cc721053be659c92b577217914905883Lloyd Pique 27818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <stdlib.h> 28293a0fb21eafd159514a0ac98d687669f9bb55b1Dennis Kempin#include <stdint.h> 29818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <assert.h> 30818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <unistd.h> 31818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <signal.h> 32818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <sys/time.h> 33818c5d8cc721053be659c92b577217914905883Lloyd Pique 34818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "wayland-private.h" 35818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "wayland-server.h" 36818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "test-runner.h" 37818c5d8cc721053be659c92b577217914905883Lloyd Pique 38818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int 39818c5d8cc721053be659c92b577217914905883Lloyd Piquefd_dispatch(int fd, uint32_t mask, void *data) 40818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 41818c5d8cc721053be659c92b577217914905883Lloyd Pique int *p = data; 42818c5d8cc721053be659c92b577217914905883Lloyd Pique 43818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(mask == 0); 44818c5d8cc721053be659c92b577217914905883Lloyd Pique ++(*p); 45818c5d8cc721053be659c92b577217914905883Lloyd Pique 46818c5d8cc721053be659c92b577217914905883Lloyd Pique return 0; 47818c5d8cc721053be659c92b577217914905883Lloyd Pique} 48818c5d8cc721053be659c92b577217914905883Lloyd Pique 49818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_post_dispatch_check) 50818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 51818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_loop *loop = wl_event_loop_create(); 52818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_source *source; 53818c5d8cc721053be659c92b577217914905883Lloyd Pique int dispatch_ran = 0; 54818c5d8cc721053be659c92b577217914905883Lloyd Pique int p[2]; 55818c5d8cc721053be659c92b577217914905883Lloyd Pique 56818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(loop); 57818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(pipe(p) == 0); 58818c5d8cc721053be659c92b577217914905883Lloyd Pique 59818c5d8cc721053be659c92b577217914905883Lloyd Pique source = wl_event_loop_add_fd(loop, p[0], WL_EVENT_READABLE, 60818c5d8cc721053be659c92b577217914905883Lloyd Pique fd_dispatch, &dispatch_ran); 61818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(source); 62818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_check(source); 63818c5d8cc721053be659c92b577217914905883Lloyd Pique 64818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_dispatch(loop, 0); 65818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(dispatch_ran == 1); 66818c5d8cc721053be659c92b577217914905883Lloyd Pique 67818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(close(p[0]) == 0); 68818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(close(p[1]) == 0); 69818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_remove(source); 70818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_destroy(loop); 71818c5d8cc721053be659c92b577217914905883Lloyd Pique} 72818c5d8cc721053be659c92b577217914905883Lloyd Pique 73818c5d8cc721053be659c92b577217914905883Lloyd Piquestruct free_source_context { 74818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_source *source1, *source2; 75818c5d8cc721053be659c92b577217914905883Lloyd Pique int p1[2], p2[2]; 76818c5d8cc721053be659c92b577217914905883Lloyd Pique int count; 77818c5d8cc721053be659c92b577217914905883Lloyd Pique}; 78818c5d8cc721053be659c92b577217914905883Lloyd Pique 79818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int 80818c5d8cc721053be659c92b577217914905883Lloyd Piquefree_source_callback(int fd, uint32_t mask, void *data) 81818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 82818c5d8cc721053be659c92b577217914905883Lloyd Pique struct free_source_context *context = data; 83818c5d8cc721053be659c92b577217914905883Lloyd Pique 84818c5d8cc721053be659c92b577217914905883Lloyd Pique context->count++; 85818c5d8cc721053be659c92b577217914905883Lloyd Pique 86818c5d8cc721053be659c92b577217914905883Lloyd Pique /* Remove other source */ 87818c5d8cc721053be659c92b577217914905883Lloyd Pique if (fd == context->p1[0]) { 88818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_remove(context->source2); 89818c5d8cc721053be659c92b577217914905883Lloyd Pique context->source2 = NULL; 90818c5d8cc721053be659c92b577217914905883Lloyd Pique } else if (fd == context->p2[0]) { 91818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_remove(context->source1); 92818c5d8cc721053be659c92b577217914905883Lloyd Pique context->source1 = NULL; 93818c5d8cc721053be659c92b577217914905883Lloyd Pique } else { 94818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(0); 95818c5d8cc721053be659c92b577217914905883Lloyd Pique } 96818c5d8cc721053be659c92b577217914905883Lloyd Pique 97818c5d8cc721053be659c92b577217914905883Lloyd Pique return 1; 98818c5d8cc721053be659c92b577217914905883Lloyd Pique} 99818c5d8cc721053be659c92b577217914905883Lloyd Pique 100818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_free_source_with_data) 101818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 102818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_loop *loop = wl_event_loop_create(); 103818c5d8cc721053be659c92b577217914905883Lloyd Pique struct free_source_context context; 104818c5d8cc721053be659c92b577217914905883Lloyd Pique int data; 105818c5d8cc721053be659c92b577217914905883Lloyd Pique 106818c5d8cc721053be659c92b577217914905883Lloyd Pique /* This test is a little tricky to get right, since we don't 107818c5d8cc721053be659c92b577217914905883Lloyd Pique * have any guarantee from the event loop (ie epoll) on the 108818c5d8cc721053be659c92b577217914905883Lloyd Pique * order of which it reports events. We want to have one 109818c5d8cc721053be659c92b577217914905883Lloyd Pique * source free the other, but we don't know which one is going 110818c5d8cc721053be659c92b577217914905883Lloyd Pique * to run first. So we add two fd sources with a callback 111818c5d8cc721053be659c92b577217914905883Lloyd Pique * that frees the other source and check that only one of them 112818c5d8cc721053be659c92b577217914905883Lloyd Pique * run (and that we don't crash, of course). 113818c5d8cc721053be659c92b577217914905883Lloyd Pique */ 114818c5d8cc721053be659c92b577217914905883Lloyd Pique 115818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(loop); 116818c5d8cc721053be659c92b577217914905883Lloyd Pique 117818c5d8cc721053be659c92b577217914905883Lloyd Pique context.count = 0; 118818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(pipe(context.p1) == 0); 119818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(pipe(context.p2) == 0); 120818c5d8cc721053be659c92b577217914905883Lloyd Pique context.source1 = 121818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_add_fd(loop, context.p1[0], WL_EVENT_READABLE, 122818c5d8cc721053be659c92b577217914905883Lloyd Pique free_source_callback, &context); 123818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(context.source1); 124818c5d8cc721053be659c92b577217914905883Lloyd Pique context.source2 = 125818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_add_fd(loop, context.p2[0], WL_EVENT_READABLE, 126818c5d8cc721053be659c92b577217914905883Lloyd Pique free_source_callback, &context); 127818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(context.source2); 128818c5d8cc721053be659c92b577217914905883Lloyd Pique 129818c5d8cc721053be659c92b577217914905883Lloyd Pique data = 5; 130818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(write(context.p1[1], &data, sizeof data) == sizeof data); 131818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(write(context.p2[1], &data, sizeof data) == sizeof data); 132818c5d8cc721053be659c92b577217914905883Lloyd Pique 133818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_dispatch(loop, 0); 134818c5d8cc721053be659c92b577217914905883Lloyd Pique 135818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(context.count == 1); 136818c5d8cc721053be659c92b577217914905883Lloyd Pique 137818c5d8cc721053be659c92b577217914905883Lloyd Pique if (context.source1) 138818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_remove(context.source1); 139818c5d8cc721053be659c92b577217914905883Lloyd Pique if (context.source2) 140818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_remove(context.source2); 141818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_destroy(loop); 142818c5d8cc721053be659c92b577217914905883Lloyd Pique 143818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(close(context.p1[0]) == 0); 144818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(close(context.p1[1]) == 0); 145818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(close(context.p2[0]) == 0); 146818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(close(context.p2[1]) == 0); 147818c5d8cc721053be659c92b577217914905883Lloyd Pique} 148818c5d8cc721053be659c92b577217914905883Lloyd Pique 149818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int 150818c5d8cc721053be659c92b577217914905883Lloyd Piquesignal_callback(int signal_number, void *data) 151818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 152818c5d8cc721053be659c92b577217914905883Lloyd Pique int *got_it = data; 153818c5d8cc721053be659c92b577217914905883Lloyd Pique 154818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(signal_number == SIGUSR1); 155818c5d8cc721053be659c92b577217914905883Lloyd Pique ++(*got_it); 156818c5d8cc721053be659c92b577217914905883Lloyd Pique 157818c5d8cc721053be659c92b577217914905883Lloyd Pique return 1; 158818c5d8cc721053be659c92b577217914905883Lloyd Pique} 159818c5d8cc721053be659c92b577217914905883Lloyd Pique 160818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_signal) 161818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 162818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_loop *loop = wl_event_loop_create(); 163818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_source *source; 164818c5d8cc721053be659c92b577217914905883Lloyd Pique int got_it = 0; 165818c5d8cc721053be659c92b577217914905883Lloyd Pique 166818c5d8cc721053be659c92b577217914905883Lloyd Pique source = wl_event_loop_add_signal(loop, SIGUSR1, 167818c5d8cc721053be659c92b577217914905883Lloyd Pique signal_callback, &got_it); 168818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(source); 169818c5d8cc721053be659c92b577217914905883Lloyd Pique 170818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_dispatch(loop, 0); 171818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(!got_it); 172818c5d8cc721053be659c92b577217914905883Lloyd Pique kill(getpid(), SIGUSR1); 173818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_dispatch(loop, 0); 174818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(got_it == 1); 175818c5d8cc721053be659c92b577217914905883Lloyd Pique 176818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_remove(source); 177818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_destroy(loop); 178818c5d8cc721053be659c92b577217914905883Lloyd Pique} 179818c5d8cc721053be659c92b577217914905883Lloyd Pique 180818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_multiple_same_signals) 181818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 182818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_loop *loop = wl_event_loop_create(); 183818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_source *s1, *s2; 184818c5d8cc721053be659c92b577217914905883Lloyd Pique int calls_no = 0; 185818c5d8cc721053be659c92b577217914905883Lloyd Pique int i; 186818c5d8cc721053be659c92b577217914905883Lloyd Pique 187818c5d8cc721053be659c92b577217914905883Lloyd Pique s1 = wl_event_loop_add_signal(loop, SIGUSR1, 188818c5d8cc721053be659c92b577217914905883Lloyd Pique signal_callback, &calls_no); 189818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(s1); 190818c5d8cc721053be659c92b577217914905883Lloyd Pique 191818c5d8cc721053be659c92b577217914905883Lloyd Pique s2 = wl_event_loop_add_signal(loop, SIGUSR1, 192818c5d8cc721053be659c92b577217914905883Lloyd Pique signal_callback, &calls_no); 193818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(s2); 194818c5d8cc721053be659c92b577217914905883Lloyd Pique 195818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_event_loop_dispatch(loop, 0) == 0); 196818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(!calls_no); 197818c5d8cc721053be659c92b577217914905883Lloyd Pique 198818c5d8cc721053be659c92b577217914905883Lloyd Pique /* Try it more times */ 199818c5d8cc721053be659c92b577217914905883Lloyd Pique for (i = 0; i < 5; ++i) { 200818c5d8cc721053be659c92b577217914905883Lloyd Pique calls_no = 0; 201818c5d8cc721053be659c92b577217914905883Lloyd Pique kill(getpid(), SIGUSR1); 202818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_event_loop_dispatch(loop, 0) == 0); 203818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(calls_no == 2); 204818c5d8cc721053be659c92b577217914905883Lloyd Pique } 205818c5d8cc721053be659c92b577217914905883Lloyd Pique 206818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_remove(s1); 207818c5d8cc721053be659c92b577217914905883Lloyd Pique 208818c5d8cc721053be659c92b577217914905883Lloyd Pique /* Try it again with one source */ 209818c5d8cc721053be659c92b577217914905883Lloyd Pique calls_no = 0; 210818c5d8cc721053be659c92b577217914905883Lloyd Pique kill(getpid(), SIGUSR1); 211818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_event_loop_dispatch(loop, 0) == 0); 212818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(calls_no == 1); 213818c5d8cc721053be659c92b577217914905883Lloyd Pique 214818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_remove(s2); 215818c5d8cc721053be659c92b577217914905883Lloyd Pique 216818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_destroy(loop); 217818c5d8cc721053be659c92b577217914905883Lloyd Pique} 218818c5d8cc721053be659c92b577217914905883Lloyd Pique 219818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int 220818c5d8cc721053be659c92b577217914905883Lloyd Piquetimer_callback(void *data) 221818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 222818c5d8cc721053be659c92b577217914905883Lloyd Pique int *got_it = data; 223818c5d8cc721053be659c92b577217914905883Lloyd Pique 224818c5d8cc721053be659c92b577217914905883Lloyd Pique ++(*got_it); 225818c5d8cc721053be659c92b577217914905883Lloyd Pique 226818c5d8cc721053be659c92b577217914905883Lloyd Pique return 1; 227818c5d8cc721053be659c92b577217914905883Lloyd Pique} 228818c5d8cc721053be659c92b577217914905883Lloyd Pique 229818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_timer) 230818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 231818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_loop *loop = wl_event_loop_create(); 232818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_source *source; 233818c5d8cc721053be659c92b577217914905883Lloyd Pique int got_it = 0; 234818c5d8cc721053be659c92b577217914905883Lloyd Pique 235818c5d8cc721053be659c92b577217914905883Lloyd Pique source = wl_event_loop_add_timer(loop, timer_callback, &got_it); 236818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(source); 237818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_timer_update(source, 10); 238818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_dispatch(loop, 0); 239818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(!got_it); 240818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_dispatch(loop, 20); 241818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(got_it == 1); 242818c5d8cc721053be659c92b577217914905883Lloyd Pique 243818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_remove(source); 244818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_destroy(loop); 245818c5d8cc721053be659c92b577217914905883Lloyd Pique} 246818c5d8cc721053be659c92b577217914905883Lloyd Pique 247818c5d8cc721053be659c92b577217914905883Lloyd Pique#define MSEC_TO_USEC(msec) ((msec) * 1000) 248818c5d8cc721053be659c92b577217914905883Lloyd Pique 249818c5d8cc721053be659c92b577217914905883Lloyd Piquestruct timer_update_context { 250818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_source *source1, *source2; 251818c5d8cc721053be659c92b577217914905883Lloyd Pique int count; 252818c5d8cc721053be659c92b577217914905883Lloyd Pique}; 253818c5d8cc721053be659c92b577217914905883Lloyd Pique 254818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int 255818c5d8cc721053be659c92b577217914905883Lloyd Piquetimer_update_callback_1(void *data) 256818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 257818c5d8cc721053be659c92b577217914905883Lloyd Pique struct timer_update_context *context = data; 258818c5d8cc721053be659c92b577217914905883Lloyd Pique 259818c5d8cc721053be659c92b577217914905883Lloyd Pique context->count++; 260818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_timer_update(context->source2, 1000); 261818c5d8cc721053be659c92b577217914905883Lloyd Pique return 1; 262818c5d8cc721053be659c92b577217914905883Lloyd Pique} 263818c5d8cc721053be659c92b577217914905883Lloyd Pique 264818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int 265818c5d8cc721053be659c92b577217914905883Lloyd Piquetimer_update_callback_2(void *data) 266818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 267818c5d8cc721053be659c92b577217914905883Lloyd Pique struct timer_update_context *context = data; 268818c5d8cc721053be659c92b577217914905883Lloyd Pique 269818c5d8cc721053be659c92b577217914905883Lloyd Pique context->count++; 270818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_timer_update(context->source1, 1000); 271818c5d8cc721053be659c92b577217914905883Lloyd Pique return 1; 272818c5d8cc721053be659c92b577217914905883Lloyd Pique} 273818c5d8cc721053be659c92b577217914905883Lloyd Pique 274818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_timer_updates) 275818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 276818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_loop *loop = wl_event_loop_create(); 277818c5d8cc721053be659c92b577217914905883Lloyd Pique struct timer_update_context context; 278818c5d8cc721053be659c92b577217914905883Lloyd Pique struct timeval start_time, end_time, interval; 279818c5d8cc721053be659c92b577217914905883Lloyd Pique 280818c5d8cc721053be659c92b577217914905883Lloyd Pique /* Create two timers that should expire at the same time (after 10ms). 281818c5d8cc721053be659c92b577217914905883Lloyd Pique * The first timer to receive its expiry callback updates the other timer 282818c5d8cc721053be659c92b577217914905883Lloyd Pique * with a much larger timeout (1s). This highlights a bug where 283818c5d8cc721053be659c92b577217914905883Lloyd Pique * wl_event_source_timer_dispatch would block for this larger timeout 284818c5d8cc721053be659c92b577217914905883Lloyd Pique * when reading from the timer fd, before calling the second timer's 285818c5d8cc721053be659c92b577217914905883Lloyd Pique * callback. 286818c5d8cc721053be659c92b577217914905883Lloyd Pique */ 287818c5d8cc721053be659c92b577217914905883Lloyd Pique 288818c5d8cc721053be659c92b577217914905883Lloyd Pique context.source1 = wl_event_loop_add_timer(loop, timer_update_callback_1, 289818c5d8cc721053be659c92b577217914905883Lloyd Pique &context); 290818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(context.source1); 291818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_event_source_timer_update(context.source1, 10) == 0); 292818c5d8cc721053be659c92b577217914905883Lloyd Pique 293818c5d8cc721053be659c92b577217914905883Lloyd Pique context.source2 = wl_event_loop_add_timer(loop, timer_update_callback_2, 294818c5d8cc721053be659c92b577217914905883Lloyd Pique &context); 295818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(context.source2); 296818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_event_source_timer_update(context.source2, 10) == 0); 297818c5d8cc721053be659c92b577217914905883Lloyd Pique 298818c5d8cc721053be659c92b577217914905883Lloyd Pique context.count = 0; 299818c5d8cc721053be659c92b577217914905883Lloyd Pique 300818c5d8cc721053be659c92b577217914905883Lloyd Pique /* Since calling the functions between source2's update and 301818c5d8cc721053be659c92b577217914905883Lloyd Pique * wl_event_loop_dispatch() takes some time, it may happen 302818c5d8cc721053be659c92b577217914905883Lloyd Pique * that only one timer expires until we call epoll_wait. 303818c5d8cc721053be659c92b577217914905883Lloyd Pique * This naturally means that only one source is dispatched 304818c5d8cc721053be659c92b577217914905883Lloyd Pique * and the test fails. To fix that, sleep 15 ms before 305818c5d8cc721053be659c92b577217914905883Lloyd Pique * calling wl_event_loop_dispatch(). That should be enough 306818c5d8cc721053be659c92b577217914905883Lloyd Pique * for the second timer to expire. 307818c5d8cc721053be659c92b577217914905883Lloyd Pique * 308818c5d8cc721053be659c92b577217914905883Lloyd Pique * https://bugs.freedesktop.org/show_bug.cgi?id=80594 309818c5d8cc721053be659c92b577217914905883Lloyd Pique */ 310818c5d8cc721053be659c92b577217914905883Lloyd Pique usleep(MSEC_TO_USEC(15)); 311818c5d8cc721053be659c92b577217914905883Lloyd Pique 312818c5d8cc721053be659c92b577217914905883Lloyd Pique gettimeofday(&start_time, NULL); 313818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_dispatch(loop, 20); 314818c5d8cc721053be659c92b577217914905883Lloyd Pique gettimeofday(&end_time, NULL); 315818c5d8cc721053be659c92b577217914905883Lloyd Pique 316818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(context.count == 2); 317818c5d8cc721053be659c92b577217914905883Lloyd Pique 318818c5d8cc721053be659c92b577217914905883Lloyd Pique /* Dispatching the events should not have taken much more than 20ms, 319818c5d8cc721053be659c92b577217914905883Lloyd Pique * since this is the timeout passed to wl_event_loop_dispatch. If it 320818c5d8cc721053be659c92b577217914905883Lloyd Pique * blocked, then it will have taken over 1s. 321818c5d8cc721053be659c92b577217914905883Lloyd Pique * Of course, it could take over 1s anyway on a very slow or heavily 322818c5d8cc721053be659c92b577217914905883Lloyd Pique * loaded system, so this test isn't 100% perfect. 323818c5d8cc721053be659c92b577217914905883Lloyd Pique */ 324818c5d8cc721053be659c92b577217914905883Lloyd Pique 325818c5d8cc721053be659c92b577217914905883Lloyd Pique timersub(&end_time, &start_time, &interval); 326818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(interval.tv_sec < 1); 327818c5d8cc721053be659c92b577217914905883Lloyd Pique 328818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_remove(context.source1); 329818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_source_remove(context.source2); 330818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_destroy(loop); 331818c5d8cc721053be659c92b577217914905883Lloyd Pique} 332818c5d8cc721053be659c92b577217914905883Lloyd Pique 333818c5d8cc721053be659c92b577217914905883Lloyd Piquestruct event_loop_destroy_listener { 334818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_listener listener; 335818c5d8cc721053be659c92b577217914905883Lloyd Pique int done; 336818c5d8cc721053be659c92b577217914905883Lloyd Pique}; 337818c5d8cc721053be659c92b577217914905883Lloyd Pique 338818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void 339818c5d8cc721053be659c92b577217914905883Lloyd Piqueevent_loop_destroy_notify(struct wl_listener *l, void *data) 340818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 341818c5d8cc721053be659c92b577217914905883Lloyd Pique struct event_loop_destroy_listener *listener = 342818c5d8cc721053be659c92b577217914905883Lloyd Pique container_of(l, struct event_loop_destroy_listener, listener); 343818c5d8cc721053be659c92b577217914905883Lloyd Pique 344818c5d8cc721053be659c92b577217914905883Lloyd Pique listener->done = 1; 345818c5d8cc721053be659c92b577217914905883Lloyd Pique} 346818c5d8cc721053be659c92b577217914905883Lloyd Pique 347818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_destroy) 348818c5d8cc721053be659c92b577217914905883Lloyd Pique{ 349818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_event_loop *loop; 350818c5d8cc721053be659c92b577217914905883Lloyd Pique struct wl_display * display; 351818c5d8cc721053be659c92b577217914905883Lloyd Pique struct event_loop_destroy_listener a, b; 352818c5d8cc721053be659c92b577217914905883Lloyd Pique 353818c5d8cc721053be659c92b577217914905883Lloyd Pique loop = wl_event_loop_create(); 354818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(loop); 355818c5d8cc721053be659c92b577217914905883Lloyd Pique 356818c5d8cc721053be659c92b577217914905883Lloyd Pique a.listener.notify = &event_loop_destroy_notify; 357818c5d8cc721053be659c92b577217914905883Lloyd Pique a.done = 0; 358818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_add_destroy_listener(loop, &a.listener); 359818c5d8cc721053be659c92b577217914905883Lloyd Pique 360818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(wl_event_loop_get_destroy_listener(loop, 361818c5d8cc721053be659c92b577217914905883Lloyd Pique event_loop_destroy_notify) == &a.listener); 362818c5d8cc721053be659c92b577217914905883Lloyd Pique 363818c5d8cc721053be659c92b577217914905883Lloyd Pique b.listener.notify = &event_loop_destroy_notify; 364818c5d8cc721053be659c92b577217914905883Lloyd Pique b.done = 0; 365818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_add_destroy_listener(loop, &b.listener); 366818c5d8cc721053be659c92b577217914905883Lloyd Pique 367818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_list_remove(&a.listener.link); 368818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_destroy(loop); 369818c5d8cc721053be659c92b577217914905883Lloyd Pique 370818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(!a.done); 371818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(b.done); 372818c5d8cc721053be659c92b577217914905883Lloyd Pique 373818c5d8cc721053be659c92b577217914905883Lloyd Pique /* Test to make sure it gets fired on display destruction */ 374818c5d8cc721053be659c92b577217914905883Lloyd Pique display = wl_display_create(); 375818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(display); 376818c5d8cc721053be659c92b577217914905883Lloyd Pique loop = wl_display_get_event_loop(display); 377818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(loop); 378818c5d8cc721053be659c92b577217914905883Lloyd Pique 379818c5d8cc721053be659c92b577217914905883Lloyd Pique a.done = 0; 380818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_event_loop_add_destroy_listener(loop, &a.listener); 381818c5d8cc721053be659c92b577217914905883Lloyd Pique 382818c5d8cc721053be659c92b577217914905883Lloyd Pique wl_display_destroy(display); 383818c5d8cc721053be659c92b577217914905883Lloyd Pique 384818c5d8cc721053be659c92b577217914905883Lloyd Pique assert(a.done); 385818c5d8cc721053be659c92b577217914905883Lloyd Pique} 386818c5d8cc721053be659c92b577217914905883Lloyd Pique 387