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 21 22 static void 23 add_and_delete(void) 24 { 25 const char *test_id = "kevent(EVFILT_USER, EV_ADD and EV_DELETE)"; 26 struct kevent kev; 27 28 test_begin(test_id); 29 30 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL); 31 test_no_kevents(); 32 33 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DELETE, 0, 0, NULL); 34 test_no_kevents(); 35 36 success(); 37 } 38 39 static void 40 event_wait(void) 41 { 42 const char *test_id = "kevent(EVFILT_USER, wait)"; 43 struct kevent kev; 44 45 test_begin(test_id); 46 47 test_no_kevents(); 48 49 /* Add the event, and then trigger it */ 50 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, NULL); 51 kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); 52 53 kev.fflags &= ~NOTE_FFCTRLMASK; 54 kev.fflags &= ~NOTE_TRIGGER; 55 kev.flags = EV_CLEAR; 56 kevent_cmp(&kev, kevent_get(kqfd)); 57 58 test_no_kevents(); 59 60 success(); 61 } 62 63 static void 64 event_wait_keepudata(void) 65 { 66 const char *test_id = "kevent(EVFILT_USER, wait w/ EV_KEEPUDATA)"; 67 struct kevent kev; 68 69 test_begin(test_id); 70 71 test_no_kevents(); 72 73 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, &kev); 74 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_KEEPUDATA, NOTE_TRIGGER, 0, 75 NULL); 76 77 kev.fflags &= ~NOTE_FFCTRLMASK; 78 kev.fflags &= ~NOTE_TRIGGER; 79 kev.flags = EV_CLEAR; 80 kev.udata = &kev; 81 kevent_cmp(&kev, kevent_get(kqfd)); 82 83 test_no_kevents(); 84 85 success(); 86 } 87 88 89 static void 90 disable_and_enable(void) 91 { 92 const char *test_id = "kevent(EVFILT_USER, EV_DISABLE and EV_ENABLE)"; 93 struct kevent kev; 94 95 test_begin(test_id); 96 97 test_no_kevents(); 98 99 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL); 100 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DISABLE, 0, 0, NULL); 101 102 /* Trigger the event, but since it is disabled, nothing will happen. */ 103 kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); 104 test_no_kevents(); 105 106 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ENABLE, 0, 0, NULL); 107 kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); 108 109 kev.flags = EV_CLEAR; 110 kev.fflags &= ~NOTE_FFCTRLMASK; 111 kev.fflags &= ~NOTE_TRIGGER; 112 kevent_cmp(&kev, kevent_get(kqfd)); 113 114 success(); 115 } 116 117 static void 118 disable_and_enable_keepudata(void) 119 { 120 const char *test_id = 121 "kevent(EVFILT_USER, EV_DISABLE and EV_ENABLE w/ EV_KEEPUDATA)"; 122 struct kevent kev; 123 124 test_begin(test_id); 125 126 test_no_kevents(); 127 128 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, &kev); 129 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DISABLE | EV_KEEPUDATA, 0, 0, 130 NULL); 131 132 /* Trigger the event, but since it is disabled, nothing will happen. */ 133 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_KEEPUDATA, NOTE_TRIGGER, 0, NULL); 134 test_no_kevents(); 135 136 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ENABLE | EV_KEEPUDATA, 0, 0, 137 NULL); 138 kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_KEEPUDATA, NOTE_TRIGGER, 0, NULL); 139 140 kev.flags = EV_CLEAR; 141 kev.fflags &= ~NOTE_FFCTRLMASK; 142 kev.fflags &= ~NOTE_TRIGGER; 143 kev.udata = &kev; 144 kevent_cmp(&kev, kevent_get(kqfd)); 145 146 success(); 147 } 148 149 static void 150 oneshot(void) 151 { 152 const char *test_id = "kevent(EVFILT_USER, EV_ONESHOT)"; 153 struct kevent kev; 154 155 test_begin(test_id); 156 157 test_no_kevents(); 158 159 kevent_add(kqfd, &kev, 2, EVFILT_USER, EV_ADD | EV_ONESHOT, 0, 0, NULL); 160 161 puts(" -- event 1"); 162 kevent_add(kqfd, &kev, 2, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); 163 164 kev.flags = EV_ONESHOT; 165 kev.fflags &= ~NOTE_FFCTRLMASK; 166 kev.fflags &= ~NOTE_TRIGGER; 167 kevent_cmp(&kev, kevent_get(kqfd)); 168 169 test_no_kevents(); 170 171 success(); 172 } 173 174 void 175 test_evfilt_user(void) 176 { 177 kqfd = kqueue(); 178 179 add_and_delete(); 180 event_wait(); 181 event_wait_keepudata(); 182 disable_and_enable(); 183 disable_and_enable_keepudata(); 184 oneshot(); 185 /* TODO: try different fflags operations */ 186 187 close(kqfd); 188 } 189