Tizen 2.1 base
[platform/upstream/gcd.git] / kqueue-1.0.4 / src / solaris / user.c
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 "sys/event.h"
18 #include "private.h"
19
20 int
21 evfilt_user_init(struct filter *filt)
22 {
23     return (0);
24 }
25
26 void
27 evfilt_user_destroy(struct filter *filt)
28 {
29     return;
30 }
31
32 int
33 evfilt_user_copyout(struct filter *filt, 
34             struct kevent *dst, 
35             int maxevents)
36 {
37     struct knote *kn;
38     int nevents = 0;
39   
40     for (kn = knote_dequeue(filt); kn != NULL; kn = knote_dequeue(filt)) {
41         memcpy(dst, &kn->kev, sizeof(*dst));
42         dst->fflags &= ~NOTE_FFCTRLMASK;     //FIXME: Not sure if needed
43         dst->fflags &= ~NOTE_TRIGGER;
44         if (kn->kev.flags & EV_ADD) {
45             /* NOTE: True on FreeBSD but not consistent behavior with
46                       other filters. */
47             dst->flags &= ~EV_ADD;
48         }
49         if (kn->kev.flags & EV_CLEAR)
50             kn->kev.fflags &= ~NOTE_TRIGGER;
51         /* FIXME: This shouldn't be necessary in Solaris...
52         if (kn->kev.flags & (EV_DISPATCH | EV_CLEAR | EV_ONESHOT))
53             eventfd_lower(filt->kf_efd);
54          */
55         if (kn->kev.flags & EV_DISPATCH) {
56             KNOTE_DISABLE(kn);
57             kn->kev.fflags &= ~NOTE_TRIGGER;
58         } else if (kn->kev.flags & EV_ONESHOT) {
59             knote_free(filt, kn);
60         }
61
62         dst++;
63         if (++nevents == maxevents)
64             break;
65     }
66
67     /* This should normally never happen but is here for debugging */
68     if (nevents == 0) {
69         dbg_puts("spurious wakeup");
70         /* FIXME: NOT IMPLEMENTED: eventfd_lower(filt->kf_efd); */
71     }
72
73     return (nevents);
74 }
75
76
77 int
78 evfilt_user_knote_create(struct filter *filt, struct knote *kn)
79 {
80 #if TODO
81     u_int ffctrl;
82
83     //determine if EV_ADD + NOTE_TRIGGER in the same kevent will cause a trigger */
84     if ((!(dst->kev.flags & EV_DISABLE)) && src->fflags & NOTE_TRIGGER) {
85         dst->kev.fflags |= NOTE_TRIGGER;
86         eventfd_raise(filt->kf_pfd);
87     }
88
89 #endif
90     return (0);
91 }
92
93 int
94 evfilt_user_knote_modify(struct filter *filt, struct knote *kn, 
95         const struct kevent *kev)
96 {
97     unsigned int ffctrl;
98     unsigned int fflags;
99
100     /* Excerpted from sys/kern/kern_event.c in FreeBSD HEAD */
101     ffctrl = kev->fflags & NOTE_FFCTRLMASK;
102     fflags = kev->fflags & NOTE_FFLAGSMASK;
103     switch (ffctrl) {
104         case NOTE_FFNOP:
105             break;
106
107         case NOTE_FFAND:
108             kn->kev.fflags &= fflags;
109             break;
110
111         case NOTE_FFOR:
112             kn->kev.fflags |= fflags;
113             break;
114
115         case NOTE_FFCOPY:
116             kn->kev.fflags = fflags;
117             break;
118
119         default:
120             /* XXX Return error? */
121             break;
122     }
123
124     if ((!(kn->kev.flags & EV_DISABLE)) && kev->fflags & NOTE_TRIGGER) {
125         kn->kev.fflags |= NOTE_TRIGGER;
126         knote_enqueue(filt, kn);
127         return (port_send(filt->kf_kqueue->kq_port, X_PORT_SOURCE_USER, NULL)); 
128     }
129
130     return (0);
131 }
132
133 int
134 evfilt_user_knote_delete(struct filter *filt, struct knote *kn)
135 {
136     return (0);
137 }
138
139 int
140 evfilt_user_knote_enable(struct filter *filt, struct knote *kn)
141 {
142     /* FIXME: what happens if NOTE_TRIGGER is in fflags?
143        should the event fire? */
144     return (0);
145 }
146
147 int
148 evfilt_user_knote_disable(struct filter *filt, struct knote *kn)
149 {
150     return (0);
151 }
152
153 const struct filter evfilt_user = {
154     EVFILT_USER,
155     evfilt_user_init,
156     evfilt_user_destroy,
157     evfilt_user_copyout,
158     evfilt_user_knote_create,
159     evfilt_user_knote_modify,
160     evfilt_user_knote_delete,
161     evfilt_user_knote_enable,
162     evfilt_user_knote_disable,   
163 };