xref: /freebsd/tests/sys/kqueue/libkqueue/user.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
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
add_and_delete(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
event_wait(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
event_wait_keepudata(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
disable_and_enable(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
disable_and_enable_keepudata(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
oneshot(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
test_evfilt_user(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