1 /* $OpenBSD: kqueue-timer.c,v 1.3 2018/05/22 19:15:22 cheloha Exp $ */ 2 /* 3 * Copyright (c) 2015 Bret Stephen Lambert <blambert@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/types.h> 19 #include <sys/time.h> 20 #include <sys/event.h> 21 22 #include <err.h> 23 #include <errno.h> 24 #include <stdio.h> 25 #include <string.h> 26 #include <unistd.h> 27 28 #include "main.h" 29 30 int 31 do_timer(void) 32 { 33 int kq, n; 34 struct kevent ev; 35 struct timespec ts; 36 37 ASS((kq = kqueue()) >= 0, 38 warn("kqueue")); 39 40 memset(&ev, 0, sizeof(ev)); 41 ev.filter = EVFILT_TIMER; 42 ev.flags = EV_ADD | EV_ENABLE | EV_ONESHOT; 43 ev.data = 500; /* 1/2 second in ms */ 44 45 n = kevent(kq, &ev, 1, NULL, 0, NULL); 46 ASSX(n != -1); 47 48 ts.tv_sec = 2; /* wait 2s for kqueue timeout */ 49 ts.tv_nsec = 0; 50 51 n = kevent(kq, NULL, 0, &ev, 1, &ts); 52 ASSX(n == 1); 53 54 /* Now retry w/o EV_ONESHOT, as EV_CLEAR is implicit */ 55 56 memset(&ev, 0, sizeof(ev)); 57 ev.filter = EVFILT_TIMER; 58 ev.flags = EV_ADD | EV_ENABLE; 59 ev.data = 500; /* 1/2 second in ms */ 60 61 n = kevent(kq, &ev, 1, NULL, 0, NULL); 62 ASSX(n != -1); 63 64 ts.tv_sec = 2; /* wait 2s for kqueue timeout */ 65 ts.tv_nsec = 0; 66 67 n = kevent(kq, NULL, 0, &ev, 1, &ts); 68 ASSX(n == 1); 69 70 return (0); 71 } 72 73 int 74 do_invalid_timer(void) 75 { 76 int i, kq, n; 77 struct kevent ev; 78 struct timespec invalid_ts[3] = { {-1, 0}, {0, -1}, {0, 1000000000L} }; 79 80 ASS((kq = kqueue()) >= 0, 81 warn("kqueue")); 82 83 memset(&ev, 0, sizeof(ev)); 84 ev.filter = EVFILT_TIMER; 85 ev.flags = EV_ADD | EV_ENABLE; 86 ev.data = 500; /* 1/2 second in ms */ 87 88 n = kevent(kq, &ev, 1, NULL, 0, NULL); 89 ASSX(n != -1); 90 91 for (i = 0; i < 3; i++) { 92 n = kevent(kq, NULL, 0, &ev, 1, &invalid_ts[i]); 93 ASS(n == -1 && errno == EINVAL, 94 warn("kevent: timeout %lld %ld", 95 (long long)invalid_ts[i].tv_sec, invalid_ts[i].tv_nsec)); 96 } 97 98 return (0); 99 } 100