xref: /freebsd/tests/sys/kqueue/libkqueue/user.c (revision 643ac419fafba89f5adda0e0ea75b538727453fb)
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