1 /* 2 * Copyright (c) 2009 Mark Heily <mark@heily.com> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * 16 * $FreeBSD$ 17 */ 18 19 #include "common.h" 20 #include <sys/time.h> 21 22 int kqfd; 23 24 void 25 test_kevent_timer_add(void) 26 { 27 const char *test_id = "kevent(EVFILT_TIMER, EV_ADD)"; 28 struct kevent kev; 29 30 test_begin(test_id); 31 32 EV_SET(&kev, 1, EVFILT_TIMER, EV_ADD, 0, 1000, NULL); 33 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 34 err(1, "%s", test_id); 35 36 success(); 37 } 38 39 void 40 test_kevent_timer_del(void) 41 { 42 const char *test_id = "kevent(EVFILT_TIMER, EV_DELETE)"; 43 struct kevent kev; 44 45 test_begin(test_id); 46 47 EV_SET(&kev, 1, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); 48 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 49 err(1, "%s", test_id); 50 51 test_no_kevents(); 52 53 success(); 54 } 55 56 void 57 test_kevent_timer_get(void) 58 { 59 const char *test_id = "kevent(EVFILT_TIMER, wait)"; 60 struct kevent kev; 61 62 test_begin(test_id); 63 64 EV_SET(&kev, 1, EVFILT_TIMER, EV_ADD, 0, 1000, NULL); 65 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 66 err(1, "%s", test_id); 67 68 kev.flags |= EV_CLEAR; 69 kev.data = 1; 70 kevent_cmp(&kev, kevent_get(kqfd)); 71 72 EV_SET(&kev, 1, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); 73 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 74 err(1, "%s", test_id); 75 76 success(); 77 } 78 79 static void 80 test_oneshot(void) 81 { 82 const char *test_id = "kevent(EVFILT_TIMER, EV_ONESHOT)"; 83 struct kevent kev; 84 85 test_begin(test_id); 86 87 test_no_kevents(); 88 89 EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 500,NULL); 90 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 91 err(1, "%s", test_id); 92 93 /* Retrieve the event */ 94 kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT; 95 kev.data = 1; 96 kevent_cmp(&kev, kevent_get(kqfd)); 97 98 /* Check if the event occurs again */ 99 sleep(3); 100 test_no_kevents(); 101 102 103 success(); 104 } 105 106 static void 107 test_periodic(void) 108 { 109 const char *test_id = "kevent(EVFILT_TIMER, periodic)"; 110 struct kevent kev; 111 112 test_begin(test_id); 113 114 test_no_kevents(); 115 116 EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD, 0, 1000,NULL); 117 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 118 err(1, "%s", test_id); 119 120 /* Retrieve the event */ 121 kev.flags = EV_ADD | EV_CLEAR; 122 kev.data = 1; 123 kevent_cmp(&kev, kevent_get(kqfd)); 124 125 /* Check if the event occurs again */ 126 sleep(1); 127 kevent_cmp(&kev, kevent_get(kqfd)); 128 129 /* Delete the event */ 130 kev.flags = EV_DELETE; 131 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 132 err(1, "%s", test_id); 133 134 success(); 135 } 136 137 static void 138 disable_and_enable(void) 139 { 140 const char *test_id = "kevent(EVFILT_TIMER, EV_DISABLE and EV_ENABLE)"; 141 struct kevent kev; 142 143 test_begin(test_id); 144 145 test_no_kevents(); 146 147 /* Add the watch and immediately disable it */ 148 EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 2000,NULL); 149 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 150 err(1, "%s", test_id); 151 kev.flags = EV_DISABLE; 152 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 153 err(1, "%s", test_id); 154 test_no_kevents(); 155 156 /* Re-enable and check again */ 157 kev.flags = EV_ENABLE; 158 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 159 err(1, "%s", test_id); 160 161 kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT; 162 kev.data = 1; 163 kevent_cmp(&kev, kevent_get(kqfd)); 164 165 success(); 166 } 167 168 static void 169 test_abstime(void) 170 { 171 const char *test_id = "kevent(EVFILT_TIMER, EV_ONESHOT, NOTE_ABSTIME)"; 172 struct kevent kev; 173 time_t when; 174 const int timeout = 3; 175 176 test_begin(test_id); 177 178 test_no_kevents(); 179 180 when = time(NULL); 181 EV_SET(&kev, vnode_fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 182 NOTE_ABSTIME | NOTE_SECONDS, when + timeout, NULL); 183 if (kevent(kqfd, &kev, 1, NULL, 0, NULL) < 0) 184 err(1, "%s", test_id); 185 186 /* Retrieve the event */ 187 kev.flags = EV_ADD | EV_ONESHOT; 188 kev.data = 1; 189 kev.fflags = 0; 190 kevent_cmp(&kev, kevent_get(kqfd)); 191 if (time(NULL) < when + timeout) 192 err(1, "too early %jd %jd", time(), when + timeout); 193 194 /* Check if the event occurs again */ 195 sleep(3); 196 test_no_kevents(); 197 198 success(); 199 } 200 201 void 202 test_evfilt_timer() 203 { 204 kqfd = kqueue(); 205 test_kevent_timer_add(); 206 test_kevent_timer_del(); 207 test_kevent_timer_get(); 208 test_oneshot(); 209 test_periodic(); 210 test_abstime(); 211 disable_and_enable(); 212 close(kqfd); 213 } 214