event.h revision 331722
112115Sdyson/*- 212115Sdyson * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org> 312115Sdyson * All rights reserved. 412115Sdyson * 512115Sdyson * Redistribution and use in source and binary forms, with or without 612115Sdyson * modification, are permitted provided that the following conditions 712115Sdyson * are met: 812115Sdyson * 1. Redistributions of source code must retain the above copyright 912115Sdyson * notice, this list of conditions and the following disclaimer. 1012115Sdyson * 2. Redistributions in binary form must reproduce the above copyright 1112115Sdyson * notice, this list of conditions and the following disclaimer in the 1212115Sdyson * documentation and/or other materials provided with the distribution. 1312115Sdyson * 1412115Sdyson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1512115Sdyson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1612115Sdyson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1712115Sdyson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1812115Sdyson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1912115Sdyson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2012115Sdyson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2112115Sdyson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2212115Sdyson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2312115Sdyson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2412115Sdyson * SUCH DAMAGE. 2512115Sdyson * 2612115Sdyson * $FreeBSD: stable/11/sys/sys/event.h 331722 2018-03-29 02:50:57Z eadler $ 2712115Sdyson */ 2812115Sdyson 2912115Sdyson#ifndef _SYS_EVENT_H_ 3012115Sdyson#define _SYS_EVENT_H_ 3112115Sdyson 3212115Sdyson#include <sys/queue.h> 3312115Sdyson 3412115Sdyson#define EVFILT_READ (-1) 3512115Sdyson#define EVFILT_WRITE (-2) 3612115Sdyson#define EVFILT_AIO (-3) /* attached to aio requests */ 3712115Sdyson#define EVFILT_VNODE (-4) /* attached to vnodes */ 3812115Sdyson#define EVFILT_PROC (-5) /* attached to struct proc */ 3912115Sdyson#define EVFILT_SIGNAL (-6) /* attached to struct proc */ 4012115Sdyson#define EVFILT_TIMER (-7) /* timers */ 4112115Sdyson#define EVFILT_PROCDESC (-8) /* attached to process descriptors */ 4213260Swollman#define EVFILT_FS (-9) /* filesystem events */ 4312115Sdyson#define EVFILT_LIO (-10) /* attached to lio requests */ 4412115Sdyson#define EVFILT_USER (-11) /* User events */ 4512115Sdyson#define EVFILT_SENDFILE (-12) /* attached to sendfile requests */ 4612115Sdyson#define EVFILT_SYSCOUNT 12 4712115Sdyson 4812115Sdyson#define EV_SET(kevp_, a, b, c, d, e, f) do { \ 4912115Sdyson struct kevent *kevp = (kevp_); \ 5012115Sdyson (kevp)->ident = (a); \ 5112115Sdyson (kevp)->filter = (b); \ 5229906Skato (kevp)->flags = (c); \ 5324131Sbde (kevp)->fflags = (d); \ 5412115Sdyson (kevp)->data = (e); \ 5512115Sdyson (kevp)->udata = (f); \ 5612115Sdyson} while(0) 5712115Sdyson 5812115Sdysonstruct kevent { 5912115Sdyson uintptr_t ident; /* identifier for this event */ 6012115Sdyson short filter; /* filter for event */ 6112115Sdyson u_short flags; 6212115Sdyson u_int fflags; 6312115Sdyson intptr_t data; 6412115Sdyson void *udata; /* opaque user data identifier */ 6512115Sdyson}; 6612115Sdyson 6712115Sdyson#if defined(_WANT_KEVENT32) || (defined(_KERNEL) && defined(__LP64__)) 6812115Sdysonstruct kevent32 { 6912115Sdyson u_int32_t ident; /* identifier for this event */ 7028270Swollman short filter; /* filter for event */ 7112911Sphk u_short flags; 7212911Sphk u_int fflags; 7312911Sphk int32_t data; 7412911Sphk u_int32_t udata; /* opaque user data identifier */ 7512911Sphk}; 7612911Sphk#endif 7712911Sphk 7812911Sphk/* actions */ 7912911Sphk#define EV_ADD 0x0001 /* add event to kq (implies enable) */ 8012911Sphk#define EV_DELETE 0x0002 /* delete event from kq */ 8112911Sphk#define EV_ENABLE 0x0004 /* enable event */ 8212911Sphk#define EV_DISABLE 0x0008 /* disable event (not reported) */ 8312911Sphk#define EV_FORCEONESHOT 0x0100 /* enable _ONESHOT and force trigger */ 8412115Sdyson 8531315Sbde/* flags */ 8630280Sphk#define EV_ONESHOT 0x0010 /* only report one occurrence */ 8712911Sphk#define EV_CLEAR 0x0020 /* clear event state after reporting */ 8812115Sdyson#define EV_RECEIPT 0x0040 /* force EV_ERROR on success, data=0 */ 8912115Sdyson#define EV_DISPATCH 0x0080 /* disable event after reporting */ 9012115Sdyson 9112115Sdyson#define EV_SYSFLAGS 0xF000 /* reserved by system */ 9212115Sdyson#define EV_DROP 0x1000 /* note should be dropped */ 9312115Sdyson#define EV_FLAG1 0x2000 /* filter-specific flag */ 9412115Sdyson#define EV_FLAG2 0x4000 /* filter-specific flag */ 9512115Sdyson 9612115Sdyson/* returned values */ 9712115Sdyson#define EV_EOF 0x8000 /* EOF detected */ 9812115Sdyson#define EV_ERROR 0x4000 /* error, data contains errno */ 9912115Sdyson 10012115Sdyson /* 10138909Sbde * data/hint flags/masks for EVFILT_USER, shared with userspace 10212115Sdyson * 10312115Sdyson * On input, the top two bits of fflags specifies how the lower twenty four 10412115Sdyson * bits should be applied to the stored value of fflags. 10512911Sphk * 10612115Sdyson * On output, the top two bits will always be set to NOTE_FFNOP and the 10716322Sgpalmer * remaining twenty four bits will contain the stored fflags value. 10816322Sgpalmer */ 10916322Sgpalmer#define NOTE_FFNOP 0x00000000 /* ignore input fflags */ 11016322Sgpalmer#define NOTE_FFAND 0x40000000 /* AND fflags */ 11116322Sgpalmer#define NOTE_FFOR 0x80000000 /* OR fflags */ 11216322Sgpalmer#define NOTE_FFCOPY 0xc0000000 /* copy fflags */ 11316322Sgpalmer#define NOTE_FFCTRLMASK 0xc0000000 /* masks for operations */ 11412115Sdyson#define NOTE_FFLAGSMASK 0x00ffffff 11516322Sgpalmer 11612115Sdyson#define NOTE_TRIGGER 0x01000000 /* Cause the event to be 11712115Sdyson triggered for output. */ 11812115Sdyson 11912115Sdyson/* 12012115Sdyson * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace 12112911Sphk */ 12212115Sdyson#define NOTE_LOWAT 0x0001 /* low water mark */ 12312115Sdyson#define NOTE_FILE_POLL 0x0002 /* behave like poll() */ 12412115Sdyson 12512115Sdyson/* 12612115Sdyson * data/hint flags for EVFILT_VNODE, shared with userspace 12712115Sdyson */ 12812115Sdyson#define NOTE_DELETE 0x0001 /* vnode was removed */ 12912115Sdyson#define NOTE_WRITE 0x0002 /* data contents changed */ 13012115Sdyson#define NOTE_EXTEND 0x0004 /* size increased */ 13129208Sbde#define NOTE_ATTRIB 0x0008 /* attributes changed */ 13229208Sbde#define NOTE_LINK 0x0010 /* link count changed */ 13329208Sbde#define NOTE_RENAME 0x0020 /* vnode was renamed */ 13429208Sbde#define NOTE_REVOKE 0x0040 /* vnode access was revoked */ 13512115Sdyson#define NOTE_OPEN 0x0080 /* vnode was opened */ 13612115Sdyson#define NOTE_CLOSE 0x0100 /* file closed, fd did not 13712115Sdyson allowed write */ 13812115Sdyson#define NOTE_CLOSE_WRITE 0x0200 /* file closed, fd did allowed 13929888Skato write */ 14029888Skato#define NOTE_READ 0x0400 /* file was read */ 14129888Skato 14229888Skato/* 14312115Sdyson * data/hint flags for EVFILT_PROC and EVFILT_PROCDESC, shared with userspace 14412115Sdyson */ 14512115Sdyson#define NOTE_EXIT 0x80000000 /* process exited */ 14612115Sdyson#define NOTE_FORK 0x40000000 /* process forked */ 14712115Sdyson#define NOTE_EXEC 0x20000000 /* process exec'd */ 14812115Sdyson#define NOTE_PCTRLMASK 0xf0000000 /* mask for hint bits */ 14912115Sdyson#define NOTE_PDATAMASK 0x000fffff /* mask for pid */ 15012115Sdyson 15112115Sdyson/* additional flags for EVFILT_PROC */ 15230469Sjulian#define NOTE_TRACK 0x00000001 /* follow across forks */ 15312115Sdyson#define NOTE_TRACKERR 0x00000002 /* could not track child */ 15412115Sdyson#define NOTE_CHILD 0x00000004 /* am a child process */ 15512115Sdyson 15612115Sdyson/* additional flags for EVFILT_TIMER */ 15712115Sdyson#define NOTE_SECONDS 0x00000001 /* data is seconds */ 15812115Sdyson#define NOTE_MSECONDS 0x00000002 /* data is milliseconds */ 15912115Sdyson#define NOTE_USECONDS 0x00000004 /* data is microseconds */ 16012115Sdyson#define NOTE_NSECONDS 0x00000008 /* data is nanoseconds */ 16112115Sdyson 16212115Sdysonstruct knote; 16312115SdysonSLIST_HEAD(klist, knote); 16412115Sdysonstruct kqueue; 16512115SdysonTAILQ_HEAD(kqlist, kqueue); 16612115Sdysonstruct knlist { 16712115Sdyson struct klist kl_list; 16812115Sdyson void (*kl_lock)(void *); /* lock function */ 16916322Sgpalmer void (*kl_unlock)(void *); 17012115Sdyson void (*kl_assert_locked)(void *); 17112115Sdyson void (*kl_assert_unlocked)(void *); 17212115Sdyson void *kl_lockarg; /* argument passed to lock functions */ 17312115Sdyson int kl_autodestroy; 17412115Sdyson}; 17512115Sdyson 17612911Sphk 17712115Sdyson#ifdef _KERNEL 17812115Sdyson 17912115Sdyson/* 18012115Sdyson * Flags for knote call 18112115Sdyson */ 18212115Sdyson#define KNF_LISTLOCKED 0x0001 /* knlist is locked */ 18312115Sdyson#define KNF_NOKQLOCK 0x0002 /* do not keep KQ_LOCK */ 18412115Sdyson 18512115Sdyson#define KNOTE(list, hint, flags) knote(list, hint, flags) 18612115Sdyson#define KNOTE_LOCKED(list, hint) knote(list, hint, KNF_LISTLOCKED) 18712115Sdyson#define KNOTE_UNLOCKED(list, hint) knote(list, hint, 0) 18812115Sdyson 18912115Sdyson#define KNLIST_EMPTY(list) SLIST_EMPTY(&(list)->kl_list) 19039028Sbde 19112115Sdyson/* 19212115Sdyson * Flag indicating hint is a signal. Used by EVFILT_SIGNAL, and also 19312115Sdyson * shared by EVFILT_PROC (all knotes attached to p->p_klist) 19412115Sdyson */ 19512115Sdyson#define NOTE_SIGNAL 0x08000000 19612115Sdyson 19729888Skato/* 19829888Skato * Hint values for the optional f_touch event filter. If f_touch is not set 19912115Sdyson * to NULL and f_isfd is zero the f_touch filter will be called with the type 20012115Sdyson * argument set to EVENT_REGISTER during a kevent() system call. It is also 20112115Sdyson * called under the same conditions with the type argument set to EVENT_PROCESS 20212115Sdyson * when the event has been triggered. 20312115Sdyson */ 20429888Skato#define EVENT_REGISTER 1 20529888Skato#define EVENT_PROCESS 2 20629888Skato 20729888Skatostruct filterops { 20812115Sdyson int f_isfd; /* true if ident == filedescriptor */ 20912115Sdyson int (*f_attach)(struct knote *kn); 21012115Sdyson void (*f_detach)(struct knote *kn); 21112115Sdyson int (*f_event)(struct knote *kn, long hint); 21222521Sdyson void (*f_touch)(struct knote *kn, struct kevent *kev, u_long type); 21312115Sdyson}; 21412115Sdyson 21522521Sdyson/* 21612115Sdyson * Setting the KN_INFLUX flag enables you to unlock the kq that this knote 21712115Sdyson * is on, and modify kn_status as if you had the KQ lock. 21812115Sdyson * 21912115Sdyson * kn_sfflags, kn_sdata, and kn_kevent are protected by the knlist lock. 22012115Sdyson */ 22139028Sbdestruct knote { 22239028Sbde SLIST_ENTRY(knote) kn_link; /* for kq */ 22339028Sbde SLIST_ENTRY(knote) kn_selnext; /* for struct selinfo */ 22439028Sbde struct knlist *kn_knlist; /* f_attach populated */ 22539028Sbde TAILQ_ENTRY(knote) kn_tqe; 22639028Sbde struct kqueue *kn_kq; /* which queue we are on */ 22739028Sbde struct kevent kn_kevent; 22839028Sbde int kn_status; /* protected by kq lock */ 22939028Sbde#define KN_ACTIVE 0x01 /* event has been triggered */ 23039028Sbde#define KN_QUEUED 0x02 /* event is on queue */ 23139028Sbde#define KN_DISABLED 0x04 /* event is disabled */ 23239028Sbde#define KN_DETACHED 0x08 /* knote is detached */ 23339028Sbde#define KN_INFLUX 0x10 /* knote is in flux */ 23439028Sbde#define KN_MARKER 0x20 /* ignore this knote */ 23539028Sbde#define KN_KQUEUE 0x40 /* this knote belongs to a kq */ 23639028Sbde#define KN_HASKQLOCK 0x80 /* for _inevent */ 23712115Sdyson#define KN_SCAN 0x100 /* flux set in kqueue_scan() */ 23839028Sbde int kn_sfflags; /* saved filter flags */ 23912115Sdyson intptr_t kn_sdata; /* saved data field */ 24012115Sdyson union { 24112115Sdyson struct file *p_fp; /* file data pointer */ 24212115Sdyson struct proc *p_proc; /* proc pointer */ 24312115Sdyson struct kaiocb *p_aio; /* AIO job pointer */ 24412115Sdyson struct aioliojob *p_lio; /* LIO job pointer */ 24512115Sdyson sbintime_t *p_nexttime; /* next timer event fires at */ 24612115Sdyson void *p_v; /* generic other pointer */ 24712115Sdyson } kn_ptr; 24812115Sdyson struct filterops *kn_fop; 24912115Sdyson void *kn_hook; 25012115Sdyson int kn_hookid; 25112115Sdyson 25212115Sdyson#define kn_id kn_kevent.ident 25312115Sdyson#define kn_filter kn_kevent.filter 25412115Sdyson#define kn_flags kn_kevent.flags 25512115Sdyson#define kn_fflags kn_kevent.fflags 25612115Sdyson#define kn_data kn_kevent.data 25712115Sdyson#define kn_fp kn_ptr.p_fp 25812115Sdyson}; 25912115Sdysonstruct kevent_copyops { 26012115Sdyson void *arg; 26112115Sdyson int (*k_copyout)(void *arg, struct kevent *kevp, int count); 26212115Sdyson int (*k_copyin)(void *arg, struct kevent *kevp, int count); 26312115Sdyson}; 26412115Sdyson 26512115Sdysonstruct thread; 26612115Sdysonstruct proc; 26712115Sdysonstruct knlist; 26839028Sbdestruct mtx; 26939028Sbdestruct rwlock; 27039028Sbde 27139028Sbdevoid knote(struct knlist *list, long hint, int lockflags); 27239028Sbdevoid knote_fork(struct knlist *list, int pid); 27339028Sbdestruct knlist *knlist_alloc(struct mtx *lock); 27439028Sbdevoid knlist_detach(struct knlist *knl); 27539028Sbdevoid knlist_add(struct knlist *knl, struct knote *kn, int islocked); 27639028Sbdevoid knlist_remove(struct knlist *knl, struct knote *kn, int islocked); 27739028Sbdeint knlist_empty(struct knlist *knl); 27839028Sbdevoid knlist_init(struct knlist *knl, void *lock, void (*kl_lock)(void *), 27939028Sbde void (*kl_unlock)(void *), void (*kl_assert_locked)(void *), 28039028Sbde void (*kl_assert_unlocked)(void *)); 28139028Sbdevoid knlist_init_mtx(struct knlist *knl, struct mtx *lock); 28239028Sbdevoid knlist_init_rw_reader(struct knlist *knl, struct rwlock *lock); 28339028Sbdevoid knlist_destroy(struct knlist *knl); 28439028Sbdevoid knlist_cleardel(struct knlist *knl, struct thread *td, 28529888Skato int islocked, int killkn); 28629888Skato#define knlist_clear(knl, islocked) \ 28729888Skato knlist_cleardel((knl), NULL, (islocked), 0) 28829888Skato#define knlist_delete(knl, td, islocked) \ 28929888Skato knlist_cleardel((knl), (td), (islocked), 1) 29012115Sdysonvoid knote_fdclose(struct thread *p, int fd); 29129888Skatoint kqfd_register(int fd, struct kevent *kev, struct thread *p, 29212115Sdyson int waitok); 29312115Sdysonint kqueue_add_filteropts(int filt, struct filterops *filtops); 29412115Sdysonint kqueue_del_filteropts(int filt); 29512115Sdyson 29612115Sdyson#else /* !_KERNEL */ 29712115Sdyson 29812115Sdyson#include <sys/cdefs.h> 29912115Sdysonstruct timespec; 30012115Sdyson 30112115Sdyson__BEGIN_DECLS 30212115Sdysonint kqueue(void); 30312115Sdysonint kevent(int kq, const struct kevent *changelist, int nchanges, 30412115Sdyson struct kevent *eventlist, int nevents, 30512115Sdyson const struct timespec *timeout); 30612115Sdyson__END_DECLS 30712115Sdyson 30812115Sdyson#endif /* !_KERNEL */ 30912115Sdyson 31012115Sdyson#endif /* !_SYS_EVENT_H_ */ 31112115Sdyson