#ifndef _SYS_EVENT_H_
#define _SYS_EVENT_H_
#define EVFILT_READ (-1)
#define EVFILT_WRITE (-2)
#define EVFILT_AIO (-3)
#define EVFILT_VNODE (-4)
#define EVFILT_PROC (-5)
#define EVFILT_SIGNAL (-6)
#define EVFILT_TIMER (-7)
#define EVFILT_DEVICE (-8)
#define EVFILT_EXCEPT (-9)
#define EVFILT_USER (-10)
#define EVFILT_SYSCOUNT 10
#define EV_SET(kevp, a, b, c, d, e, f) do { \
struct kevent *__kevp = (kevp); \
(__kevp)->ident = (a); \
(__kevp)->filter = (b); \
(__kevp)->flags = (c); \
(__kevp)->fflags = (d); \
(__kevp)->data = (e); \
(__kevp)->udata = (f); \
} while(0)
struct kevent {
__uintptr_t ident;
short filter;
unsigned short flags;
unsigned int fflags;
__int64_t data;
void *udata;
};
#define EV_ADD 0x0001
#define EV_DELETE 0x0002
#define EV_ENABLE 0x0004
#define EV_DISABLE 0x0008
#define EV_ONESHOT 0x0010
#define EV_CLEAR 0x0020
#define EV_RECEIPT 0x0040
#define EV_DISPATCH 0x0080
#define EV_SYSFLAGS 0xf800
#define EV_FLAG1 0x2000
#define EV_EOF 0x8000
#define EV_ERROR 0x4000
#define NOTE_LOWAT 0x0001
#define NOTE_EOF 0x0002
#define NOTE_OOB 0x0004
#define NOTE_DELETE 0x0001
#define NOTE_WRITE 0x0002
#define NOTE_EXTEND 0x0004
#define NOTE_ATTRIB 0x0008
#define NOTE_LINK 0x0010
#define NOTE_RENAME 0x0020
#define NOTE_REVOKE 0x0040
#define NOTE_TRUNCATE 0x0080
#define NOTE_EXIT 0x80000000
#define NOTE_FORK 0x40000000
#define NOTE_EXEC 0x20000000
#define NOTE_PCTRLMASK 0xf0000000
#define NOTE_PDATAMASK 0x000fffff
#define NOTE_TRACK 0x00000001
#define NOTE_TRACKERR 0x00000002
#define NOTE_CHILD 0x00000004
#define NOTE_CHANGE 0x00000001
#define NOTE_MSECONDS 0x00000000
#define NOTE_SECONDS 0x00000001
#define NOTE_USECONDS 0x00000002
#define NOTE_NSECONDS 0x00000003
#define NOTE_ABSTIME 0x00000010
#define NOTE_FFNOP 0x00000000
#define NOTE_FFAND 0x40000000
#define NOTE_FFOR 0x80000000
#define NOTE_FFCOPY 0xc0000000
#define NOTE_FFCTRLMASK 0xc0000000
#define NOTE_FFLAGSMASK 0x00ffffff
#define NOTE_TRIGGER 0x01000000
#include <sys/queue.h>
struct klistops;
struct knote;
SLIST_HEAD(knlist, knote);
struct klist {
struct knlist kl_list;
const struct klistops *kl_ops;
void *kl_arg;
};
#ifdef _KERNEL
#define __EV_SELECT 0x0800
#define __EV_POLL 0x1000
#define __EV_HUP EV_FLAG1
#define EVFILT_MARKER 0xf
#define NOTE_SUBMIT 0x01000000
#define KN_HASHSIZE 64
#define NOTE_SIGNAL 0x08000000
#define FILTEROP_ISFD 0x00000001
#define FILTEROP_MPSAFE 0x00000002
struct filterops {
int f_flags;
int (*f_attach)(struct knote *kn);
void (*f_detach)(struct knote *kn);
int (*f_event)(struct knote *kn, long hint);
int (*f_modify)(struct kevent *kev, struct knote *kn);
int (*f_process)(struct knote *kn, struct kevent *kev);
};
struct knote {
SLIST_ENTRY(knote) kn_link;
SLIST_ENTRY(knote) kn_selnext;
TAILQ_ENTRY(knote) kn_tqe;
struct kqueue *kn_kq;
struct kevent kn_kevent;
int kn_status;
int kn_sfflags;
__int64_t kn_sdata;
union {
struct file *p_fp;
struct process *p_process;
int p_useract;
} kn_ptr;
const struct filterops *kn_fop;
void *kn_hook;
unsigned int kn_pollid;
#define KN_ACTIVE 0x0001
#define KN_QUEUED 0x0002
#define KN_DISABLED 0x0004
#define KN_DETACHED 0x0008
#define KN_PROCESSING 0x0010
#define KN_WAITING 0x0020
#define kn_id kn_kevent.ident
#define kn_filter kn_kevent.filter
#define kn_flags kn_kevent.flags
#define kn_fflags kn_kevent.fflags
#define kn_data kn_kevent.data
#define kn_udata kn_kevent.udata
#define kn_fp kn_ptr.p_fp
};
struct klistops {
void (*klo_assertlk)(void *);
int (*klo_lock)(void *);
void (*klo_unlock)(void *, int);
};
struct kqueue_scan_state {
struct kqueue *kqs_kq;
struct knote kqs_start;
struct knote kqs_end;
int kqs_nevent;
int kqs_queued;
};
struct mutex;
struct proc;
struct rwlock;
struct timespec;
extern const struct filterops dead_filtops;
extern void kqpoll_init(unsigned int);
extern void kqpoll_done(unsigned int);
extern void kqpoll_exit(void);
extern void knote(struct klist *list, long hint);
extern void knote_locked(struct klist *list, long hint);
extern void knote_fdclose(struct proc *p, int fd);
extern void knote_processexit(struct process *);
extern void knote_processfork(struct process *, pid_t);
extern void knote_assign(const struct kevent *, struct knote *);
extern void knote_submit(struct knote *, struct kevent *);
extern void kqueue_init(void);
extern void kqueue_init_percpu(void);
extern int kqueue_register(struct kqueue *kq, struct kevent *kev,
unsigned int pollid, struct proc *p);
extern int kqueue_scan(struct kqueue_scan_state *, int, struct kevent *,
struct timespec *, struct proc *, int *);
extern void kqueue_scan_setup(struct kqueue_scan_state *, struct kqueue *);
extern void kqueue_scan_finish(struct kqueue_scan_state *);
extern int filt_seltrue(struct knote *kn, long hint);
extern int seltrue_kqfilter(dev_t, struct knote *);
extern void klist_init(struct klist *, const struct klistops *, void *);
extern void klist_init_mutex(struct klist *, struct mutex *);
extern void klist_init_rwlock(struct klist *, struct rwlock *);
extern void klist_free(struct klist *);
extern void klist_insert(struct klist *, struct knote *);
extern void klist_insert_locked(struct klist *, struct knote *);
extern void klist_remove(struct klist *, struct knote *);
extern void klist_remove_locked(struct klist *, struct knote *);
extern void klist_invalidate(struct klist *);
static inline int
knote_modify_fn(const struct kevent *kev, struct knote *kn,
int (*f_event)(struct knote *, long))
{
knote_assign(kev, kn);
return ((*f_event)(kn, 0));
}
static inline int
knote_modify(const struct kevent *kev, struct knote *kn)
{
return (knote_modify_fn(kev, kn, kn->kn_fop->f_event));
}
static inline int
knote_process_fn(struct knote *kn, struct kevent *kev,
int (*f_event)(struct knote *, long))
{
int active;
if (kev != NULL && (kn->kn_flags & EV_ONESHOT))
active = 1;
else
active = (*f_event)(kn, 0);
if (active)
knote_submit(kn, kev);
return (active);
}
static inline int
knote_process(struct knote *kn, struct kevent *kev)
{
return (knote_process_fn(kn, kev, kn->kn_fop->f_event));
}
static inline int
klist_empty(struct klist *klist)
{
return (SLIST_EMPTY(&klist->kl_list));
}
#else
#include <sys/cdefs.h>
struct timespec;
__BEGIN_DECLS
int kqueue(void);
int kqueue1(int flags);
int kevent(int kq, const struct kevent *changelist, int nchanges,
struct kevent *eventlist, int nevents,
const struct timespec *timeout);
__END_DECLS
#endif
#endif