DEV Community

Shaowen Zhu
Shaowen Zhu

Posted on

Simple Kqueue Echo Server in C


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);
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode
  • 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

kqueue

Streaming Server Using Kqueue

Top comments (0)