Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:14

0001 /*-
0002  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
0003  *
0004  * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
0005  * All rights reserved.
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions and the following disclaimer.
0012  * 2. Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *
0016  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0017  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0019  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
0020  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0021  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0022  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0023  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0024  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0025  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0026  * SUCH DAMAGE.
0027  *
0028  * $FreeBSD: head/sys/sys/event.h 336457 2018-07-18 13:04:03Z dab $
0029  */
0030 
0031 #ifndef _SYS_EVENT_H_
0032 #define _SYS_EVENT_H_
0033 
0034 #include <sys/_types.h>
0035 #include <sys/queue.h>
0036 
0037 #define EVFILT_READ     (-1)
0038 #define EVFILT_WRITE        (-2)
0039 #define EVFILT_AIO      (-3)    /* attached to aio requests */
0040 #define EVFILT_VNODE        (-4)    /* attached to vnodes */
0041 #define EVFILT_PROC     (-5)    /* attached to struct proc */
0042 #define EVFILT_SIGNAL       (-6)    /* attached to struct proc */
0043 #define EVFILT_TIMER        (-7)    /* timers */
0044 #define EVFILT_PROCDESC     (-8)    /* attached to process descriptors */
0045 #define EVFILT_FS       (-9)    /* filesystem events */
0046 #define EVFILT_LIO      (-10)   /* attached to lio requests */
0047 #define EVFILT_USER     (-11)   /* User events */
0048 #define EVFILT_SENDFILE     (-12)   /* attached to sendfile requests */
0049 #define EVFILT_EMPTY        (-13)   /* empty send socket buf */
0050 #define EVFILT_SYSCOUNT     13
0051 
0052 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
0053 #define EV_SET(kevp_, a, b, c, d, e, f) do {    \
0054     *(kevp_) = (struct kevent){     \
0055         .ident = (a),           \
0056         .filter = (b),          \
0057         .flags = (c),           \
0058         .fflags = (d),          \
0059         .data = (e),            \
0060         .udata = (f),           \
0061         .ext = {0},             \
0062     };                  \
0063 } while(0)
0064 #else /* Pre-C99 or not STDC (e.g., C++) */
0065 /* The definition of the local variable kevp could possibly conflict
0066  * with a user-defined value passed in parameters a-f.
0067  */
0068 #define EV_SET(kevp_, a, b, c, d, e, f) do {    \
0069     struct kevent *kevp = (kevp_);      \
0070     (kevp)->ident = (a);            \
0071     (kevp)->filter = (b);           \
0072     (kevp)->flags = (c);            \
0073     (kevp)->fflags = (d);           \
0074     (kevp)->data = (e);         \
0075     (kevp)->udata = (f);            \
0076     (kevp)->ext[0] = 0;         \
0077     (kevp)->ext[1] = 0;         \
0078     (kevp)->ext[2] = 0;         \
0079     (kevp)->ext[3] = 0;         \
0080 } while(0)
0081 #endif
0082 
0083 struct kevent {
0084     __uintptr_t ident;      /* identifier for this event */
0085     short       filter;     /* filter for event */
0086     unsigned short  flags;      /* action flags for kqueue */
0087     unsigned int    fflags;     /* filter flag value */
0088     __int64_t   data;       /* filter data value */
0089     void        *udata;     /* opaque user data identifier */
0090     __uint64_t  ext[4];     /* extensions */
0091 };
0092 
0093 #if defined(_WANT_FREEBSD11_KEVENT)
0094 /* Older structure used in FreeBSD 11.x and older. */
0095 struct kevent_freebsd11 {
0096     __uintptr_t ident;      /* identifier for this event */
0097     short       filter;     /* filter for event */
0098     unsigned short  flags;
0099     unsigned int    fflags;
0100     __intptr_t  data;
0101     void        *udata;     /* opaque user data identifier */
0102 };
0103 #endif
0104 
0105 #if defined(_WANT_KEVENT32) || (defined(_KERNEL) && defined(__LP64__))
0106 struct kevent32 {
0107     uint32_t    ident;      /* identifier for this event */
0108     short       filter;     /* filter for event */
0109     u_short     flags;
0110     u_int       fflags;
0111 #ifndef __amd64__
0112     uint32_t    pad0;
0113 #endif
0114     int32_t     data1, data2;
0115     uint32_t    udata;      /* opaque user data identifier */
0116 #ifndef __amd64__
0117     uint32_t    pad1;
0118 #endif
0119     uint32_t    ext64[8];
0120 };
0121 
0122 #ifdef _WANT_FREEBSD11_KEVENT
0123 struct kevent32_freebsd11 {
0124     u_int32_t   ident;      /* identifier for this event */
0125     short       filter;     /* filter for event */
0126     u_short     flags;
0127     u_int       fflags;
0128     int32_t     data;
0129     u_int32_t   udata;      /* opaque user data identifier */
0130 };
0131 #endif
0132 #endif
0133 
0134 /* actions */
0135 #define EV_ADD      0x0001      /* add event to kq (implies enable) */
0136 #define EV_DELETE   0x0002      /* delete event from kq */
0137 #define EV_ENABLE   0x0004      /* enable event */
0138 #define EV_DISABLE  0x0008      /* disable event (not reported) */
0139 #define EV_FORCEONESHOT 0x0100      /* enable _ONESHOT and force trigger */
0140 
0141 /* flags */
0142 #define EV_ONESHOT  0x0010      /* only report one occurrence */
0143 #define EV_CLEAR    0x0020      /* clear event state after reporting */
0144 #define EV_RECEIPT  0x0040      /* force EV_ERROR on success, data=0 */
0145 #define EV_DISPATCH 0x0080      /* disable event after reporting */
0146 
0147 #define EV_SYSFLAGS 0xF000      /* reserved by system */
0148 #define EV_DROP     0x1000      /* note should be dropped */
0149 #define EV_FLAG1    0x2000      /* filter-specific flag */
0150 #define EV_FLAG2    0x4000      /* filter-specific flag */
0151 
0152 /* returned values */
0153 #define EV_EOF      0x8000      /* EOF detected */
0154 #define EV_ERROR    0x4000      /* error, data contains errno */
0155 
0156  /*
0157   * data/hint flags/masks for EVFILT_USER, shared with userspace
0158   *
0159   * On input, the top two bits of fflags specifies how the lower twenty four
0160   * bits should be applied to the stored value of fflags.
0161   *
0162   * On output, the top two bits will always be set to NOTE_FFNOP and the
0163   * remaining twenty four bits will contain the stored fflags value.
0164   */
0165 #define NOTE_FFNOP  0x00000000      /* ignore input fflags */
0166 #define NOTE_FFAND  0x40000000      /* AND fflags */
0167 #define NOTE_FFOR   0x80000000      /* OR fflags */
0168 #define NOTE_FFCOPY 0xc0000000      /* copy fflags */
0169 #define NOTE_FFCTRLMASK 0xc0000000      /* masks for operations */
0170 #define NOTE_FFLAGSMASK 0x00ffffff
0171 
0172 #define NOTE_TRIGGER    0x01000000      /* Cause the event to be
0173                            triggered for output. */
0174 
0175 /*
0176  * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
0177  */
0178 #define NOTE_LOWAT  0x0001          /* low water mark */
0179 #define NOTE_FILE_POLL  0x0002          /* behave like poll() */
0180 
0181 /*
0182  * data/hint flags for EVFILT_VNODE, shared with userspace
0183  */
0184 #define NOTE_DELETE 0x0001          /* vnode was removed */
0185 #define NOTE_WRITE  0x0002          /* data contents changed */
0186 #define NOTE_EXTEND 0x0004          /* size increased */
0187 #define NOTE_ATTRIB 0x0008          /* attributes changed */
0188 #define NOTE_LINK   0x0010          /* link count changed */
0189 #define NOTE_RENAME 0x0020          /* vnode was renamed */
0190 #define NOTE_REVOKE 0x0040          /* vnode access was revoked */
0191 #define NOTE_OPEN   0x0080          /* vnode was opened */
0192 #define NOTE_CLOSE  0x0100          /* file closed, fd did not
0193                            allowed write */
0194 #define NOTE_CLOSE_WRITE 0x0200         /* file closed, fd did allowed
0195                            write */
0196 #define NOTE_READ   0x0400          /* file was read */
0197 
0198 /*
0199  * data/hint flags for EVFILT_PROC and EVFILT_PROCDESC, shared with userspace
0200  */
0201 #define NOTE_EXIT   0x80000000      /* process exited */
0202 #define NOTE_FORK   0x40000000      /* process forked */
0203 #define NOTE_EXEC   0x20000000      /* process exec'd */
0204 #define NOTE_PCTRLMASK  0xf0000000      /* mask for hint bits */
0205 #define NOTE_PDATAMASK  0x000fffff      /* mask for pid */
0206 
0207 /* additional flags for EVFILT_PROC */
0208 #define NOTE_TRACK  0x00000001      /* follow across forks */
0209 #define NOTE_TRACKERR   0x00000002      /* could not track child */
0210 #define NOTE_CHILD  0x00000004      /* am a child process */
0211 
0212 /* additional flags for EVFILT_TIMER */
0213 #define NOTE_SECONDS        0x00000001  /* data is seconds */
0214 #define NOTE_MSECONDS       0x00000002  /* data is milliseconds */
0215 #define NOTE_USECONDS       0x00000004  /* data is microseconds */
0216 #define NOTE_NSECONDS       0x00000008  /* data is nanoseconds */
0217 #define NOTE_ABSTIME        0x00000010  /* timeout is absolute */
0218 
0219 struct knote;
0220 SLIST_HEAD(klist, knote);
0221 struct kqueue;
0222 TAILQ_HEAD(kqlist, kqueue);
0223 struct knlist {
0224     struct  klist   kl_list;
0225     void    (*kl_lock)(void *); /* lock function */
0226     void    (*kl_unlock)(void *);
0227     void    (*kl_assert_locked)(void *);
0228     void    (*kl_assert_unlocked)(void *);
0229     void    *kl_lockarg;        /* argument passed to lock functions */
0230     int kl_autodestroy;
0231 };
0232 
0233 
0234 #ifdef _KERNEL
0235 
0236 /*
0237  * Flags for knote call
0238  */
0239 #define KNF_LISTLOCKED  0x0001          /* knlist is locked */
0240 #define KNF_NOKQLOCK    0x0002          /* do not keep KQ_LOCK */
0241 
0242 #define KNOTE(list, hint, flags)    knote(list, hint, flags)
0243 #define KNOTE_LOCKED(list, hint)    knote(list, hint, KNF_LISTLOCKED)
0244 #define KNOTE_UNLOCKED(list, hint)  knote(list, hint, 0)
0245 
0246 #define KNLIST_EMPTY(list)      SLIST_EMPTY(&(list)->kl_list)
0247 
0248 /*
0249  * Flag indicating hint is a signal.  Used by EVFILT_SIGNAL, and also
0250  * shared by EVFILT_PROC  (all knotes attached to p->p_klist)
0251  */
0252 #define NOTE_SIGNAL 0x08000000
0253 
0254 /*
0255  * Hint values for the optional f_touch event filter.  If f_touch is not set 
0256  * to NULL and f_isfd is zero the f_touch filter will be called with the type
0257  * argument set to EVENT_REGISTER during a kevent() system call.  It is also
0258  * called under the same conditions with the type argument set to EVENT_PROCESS
0259  * when the event has been triggered.
0260  */
0261 #define EVENT_REGISTER  1
0262 #define EVENT_PROCESS   2
0263 
0264 struct filterops {
0265     int f_isfd;     /* true if ident == filedescriptor */
0266     int (*f_attach)(struct knote *kn);
0267     void    (*f_detach)(struct knote *kn);
0268     int (*f_event)(struct knote *kn, long hint);
0269     void    (*f_touch)(struct knote *kn, struct kevent *kev, u_long type);
0270 };
0271 
0272 /*
0273  * An in-flux knote cannot be dropped from its kq while the kq is
0274  * unlocked.  If the KN_SCAN flag is not set, a thread can only set
0275  * kn_influx when it is exclusive owner of the knote state, and can
0276  * modify kn_status as if it had the KQ lock.  KN_SCAN must not be set
0277  * on a knote which is already in flux.
0278  *
0279  * kn_sfflags, kn_sdata, and kn_kevent are protected by the knlist lock.
0280  */
0281 struct knote {
0282     SLIST_ENTRY(knote)  kn_link;    /* for kq */
0283     SLIST_ENTRY(knote)  kn_selnext; /* for struct selinfo */
0284     struct          knlist *kn_knlist;  /* f_attach populated */
0285     TAILQ_ENTRY(knote)  kn_tqe;
0286     struct          kqueue *kn_kq;  /* which queue we are on */
0287     struct          kevent kn_kevent;
0288     void            *kn_hook;
0289     int         kn_hookid;
0290     int         kn_status;  /* protected by kq lock */
0291 #define KN_ACTIVE   0x01            /* event has been triggered */
0292 #define KN_QUEUED   0x02            /* event is on queue */
0293 #define KN_DISABLED 0x04            /* event is disabled */
0294 #define KN_DETACHED 0x08            /* knote is detached */
0295 #define KN_MARKER   0x20            /* ignore this knote */
0296 #define KN_KQUEUE   0x40            /* this knote belongs to a kq */
0297 #define KN_HASKQLOCK    0x80            /* for _inevent */
0298 #define KN_SCAN     0x100           /* flux set in kqueue_scan() */
0299     int         kn_influx;
0300     int         kn_sfflags; /* saved filter flags */
0301     int64_t         kn_sdata;   /* saved data field */
0302     union {
0303         struct      file *p_fp; /* file data pointer */
0304         struct      proc *p_proc;   /* proc pointer */
0305         struct      kaiocb *p_aio;  /* AIO job pointer */
0306         struct      aioliojob *p_lio;   /* LIO job pointer */
0307         void        *p_v;       /* generic other pointer */
0308     } kn_ptr;
0309     struct          filterops *kn_fop;
0310 
0311 #define kn_id       kn_kevent.ident
0312 #define kn_filter   kn_kevent.filter
0313 #define kn_flags    kn_kevent.flags
0314 #define kn_fflags   kn_kevent.fflags
0315 #define kn_data     kn_kevent.data
0316 #define kn_fp       kn_ptr.p_fp
0317 };
0318 struct kevent_copyops {
0319     void    *arg;
0320     int (*k_copyout)(void *arg, struct kevent *kevp, int count);
0321     int (*k_copyin)(void *arg, struct kevent *kevp, int count);
0322     size_t  kevent_size;
0323 };
0324 
0325 struct thread;
0326 struct proc;
0327 struct knlist;
0328 struct mtx;
0329 struct rwlock;
0330 
0331 void    knote(struct knlist *list, long hint, int lockflags);
0332 void    knote_fork(struct knlist *list, int pid);
0333 struct knlist *knlist_alloc(struct mtx *lock);
0334 void    knlist_detach(struct knlist *knl);
0335 void    knlist_add(struct knlist *knl, struct knote *kn, int islocked);
0336 void    knlist_remove(struct knlist *knl, struct knote *kn, int islocked);
0337 int knlist_empty(struct knlist *knl);
0338 void    knlist_init(struct knlist *knl, void *lock, void (*kl_lock)(void *),
0339         void (*kl_unlock)(void *), void (*kl_assert_locked)(void *),
0340         void (*kl_assert_unlocked)(void *));
0341 void    knlist_init_mtx(struct knlist *knl, struct mtx *lock);
0342 void    knlist_init_rw_reader(struct knlist *knl, struct rwlock *lock);
0343 void    knlist_destroy(struct knlist *knl);
0344 void    knlist_cleardel(struct knlist *knl, struct thread *td,
0345         int islocked, int killkn);
0346 #define knlist_clear(knl, islocked)             \
0347     knlist_cleardel((knl), NULL, (islocked), 0)
0348 #define knlist_delete(knl, td, islocked)            \
0349     knlist_cleardel((knl), (td), (islocked), 1)
0350 void    knote_fdclose(struct thread *p, int fd);
0351 int     kqfd_register(int fd, struct kevent *kev, struct thread *p,
0352         int waitok);
0353 int kqueue_add_filteropts(int filt, struct filterops *filtops);
0354 int kqueue_del_filteropts(int filt);
0355 
0356 #else   /* !_KERNEL */
0357 
0358 #include <sys/cdefs.h>
0359 struct timespec;
0360 
0361 __BEGIN_DECLS
0362 int     kqueue(void);
0363 int     kevent(int kq, const struct kevent *changelist, int nchanges,
0364         struct kevent *eventlist, int nevents,
0365         const struct timespec *timeout);
0366 __END_DECLS
0367 
0368 #endif /* !_KERNEL */
0369 
0370 #endif /* !_SYS_EVENT_H_ */