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
21int kqfd;
22
23static void
24add_and_delete(void)
25{
26    const char *test_id = "kevent(EVFILT_USER, EV_ADD and EV_DELETE)";
27    struct kevent kev;
28
29    test_begin(test_id);
30
31    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL);
32    test_no_kevents();
33
34    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DELETE, 0, 0, NULL);
35    test_no_kevents();
36
37    success();
38}
39
40static void
41event_wait(void)
42{
43    const char *test_id = "kevent(EVFILT_USER, wait)";
44    struct kevent kev;
45
46    test_begin(test_id);
47
48    test_no_kevents();
49
50    /* Add the event, and then trigger it */
51    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, NULL);
52    kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
53
54    kev.fflags &= ~NOTE_FFCTRLMASK;
55    kev.fflags &= ~NOTE_TRIGGER;
56    kev.flags = EV_CLEAR;
57    kevent_cmp(&kev, kevent_get(kqfd));
58
59    test_no_kevents();
60
61    success();
62}
63
64static void
65disable_and_enable(void)
66{
67    const char *test_id = "kevent(EVFILT_USER, EV_DISABLE and EV_ENABLE)";
68    struct kevent kev;
69
70    test_begin(test_id);
71
72    test_no_kevents();
73
74    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL);
75    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DISABLE, 0, 0, NULL);
76
77    /* Trigger the event, but since it is disabled, nothing will happen. */
78    kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
79    test_no_kevents();
80
81    kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ENABLE, 0, 0, NULL);
82    kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
83
84    kev.flags = EV_CLEAR;
85    kev.fflags &= ~NOTE_FFCTRLMASK;
86    kev.fflags &= ~NOTE_TRIGGER;
87    kevent_cmp(&kev, kevent_get(kqfd));
88
89    success();
90}
91
92static void
93oneshot(void)
94{
95    const char *test_id = "kevent(EVFILT_USER, EV_ONESHOT)";
96    struct kevent kev;
97
98    test_begin(test_id);
99
100    test_no_kevents();
101
102    kevent_add(kqfd, &kev, 2, EVFILT_USER, EV_ADD | EV_ONESHOT, 0, 0, NULL);
103
104    puts("  -- event 1");
105    kevent_add(kqfd, &kev, 2, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
106
107    kev.flags = EV_ONESHOT;
108    kev.fflags &= ~NOTE_FFCTRLMASK;
109    kev.fflags &= ~NOTE_TRIGGER;
110    kevent_cmp(&kev, kevent_get(kqfd));
111
112    test_no_kevents();
113
114    success();
115}
116
117void
118test_evfilt_user()
119{
120	kqfd = kqueue();
121
122    add_and_delete();
123    event_wait();
124    disable_and_enable();
125    oneshot();
126    /* TODO: try different fflags operations */
127
128	close(kqfd);
129}
130