There are three important functions when use kqueue.
int kqueue(void);
int kevent(int kq,
const struct kevent* changelist, int nchanges,
struct kevent *eventlist, int nevents,
const struct timespec *timeout);
EV_SET(kev, ident, filter, flags, fflags, data, udata);
The
kqueue()
system call creates a new kernel event queue and returns a descriptor.The
kevent()
system call is used to register events with the queue, and return any pending events to the user.
- change kqueue
When you want to change the queue, like delete a socket file descriptor from kqueue for example, or add listen socket to kqueue, you can call kevent()
like below:
int kq = kqueue();
struct kevent event;
EV_SET(&event, listen_fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
kevent(kq, &event, 1, NULL, 0, NULL);
As the codes above, when we want to change(delete/add) a event to a kqueue, there are two steps, first thing we should do is to initialize kevent with a file descriptor we want to monitor, secondly is to add this kevent to kqueue using kevent()
.
- monitor kqueue
When we want to monitor kqueue, we don't have to provide changelist
and nchanges
parameter of kevent()
. We just need to provide these two parameters: eventlist
and nevents
, like below:
struct kevent event_list[MAX_EVENTS];
int num_events = kevent(kq, NULL, 0, event_list, MAX_EVENTS, NULL);
- remove kevent
When a client disconnect, we don't care(monitor) the kevent associated with this client anymore, so we need to remove this kevent from kqueue. But we don't have to call EV_SET()
and kevent()
, we just need to close this file descriptor. Cause the man page says below:
Calling close() on a file descriptor will remove any kevents that reference the descriptor.
- source code
- reference
Top comments (0)