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