Menu

Usage

Mark Heily

Usage

Here are some issues to be aware of when using this library under any platform:

  • The EVFILT_PROC filter is not implemented.
  • The EVFILT_AIO filter is not implemented.
  • When a kqueue descriptor is closed, it's resources are not immediately reclaimed. Instead, they will be freed the next time that the kqueue() function is called.
  • A signal handler is implicitly installed when a EVFILT_SIGNAL kevent is created. For compatibility with kernel-based kqueue(2), programs must ignore signals that will generate kevents. After an EVFILT_SIGNAL kevent is created, a program must not modify the disposition of the associated signal. The following example shows the proper way to handle SIGUSR1 with a kevent:
int main() {
  int kqfd;
  struct kevent kev;

  kqfd = kqueue();
  signal(SIGUSR1, SIG_IGN);
  EV_SET(&kev, SIGUSR1, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
  kevent(kqfd, &kev, 1, NULL, 0, NULL);
}

There are additional considerations listed below that are platform-specific.

Linux

There are several compatibility issues to be aware of when using this library under Linux:

  • The NOTE_LOWAT flag is not supported. According to socket(7),
            "The select(2) and poll(2) system  calls  currently  do not respect the 
    SO_RCVLOWAT setting on Linux, and mark a socket readable when even  a  
    single  byte  of data is available.  A subsequent read from the socket 
    will block until SO_RCVLOWAT bytes are available."
    
  • The NOTE_REVOKE flag is not supported because Linux does not have a revoke(2) system call.
  • When an EVFILT_SIGNAL event is generated, the data field is set to 1 regardless of how many times the signal was received by the process.
  • When an EVFILT_READ event occurs on a listening socket, the data field is set to 1 regardless of how many pending connections are available.

Solaris

Here are the issues to be aware of when using this library under Solaris:

  • Solaris 10 or newer is required. It should work with OpenSolaris? and other Solaris-based distributions, but has not been tested.
  • When an EVFILT_READ event is generated, the data field is set to 1 regardless of how many bytes are available to read.
  • When an EVFILT_TIMER event is generated, the data field is set to 1 regardless of how many times the timer has been triggered.
  • The EVFILT_VNODE filter is not implemented. This will eventually be implemented using the PORT_SOURCE_FILE mechanism described here.
  • The EVFILT_TIMER filter is implemented using high-resolution timers. In order to use high-resolution timers, the calling process must hold the PRIV_PROC_CLOCK_HIGHRES privilege. This privilege is not granted to ordinary users by default. It can be granted to individual users by running the following command as root:
            # usermod -K defaultpriv=basic,proc_clock_highres $user
    

BSD-based systems

There are some differences in the behavior of the kevent(2) system call across the various BSD-based operating systems. Here are some of the differences to be aware of:

  • FreeBSD 8 does not set the EV_ADD flag for kevents on the eventlist, but OpenBSD and Darwin do. This means you should never use the equality operator (==) to test the flags; use the logical AND operator instead.
  • The EVFILT_USER filter behaves differently from other filters with respect to the EV_ONESHOT flag. All other filters will preserve the flag when the event is triggered and placed on the eventlist. The EVFILT_USER filter does not preserve this flag.
  • OpenBSD has the NOTE_TRUNCATE fflag, while FreeBSD and Darwin do not.
  • EVFILT_FS is undocumented and only available on FreeBSD and Darwin. Here is the CVS commit log which could be helpful to document this filter.

Integration

Ordinary Makefile

Here are the steps to use libkqueue in your program if you use an ordinary Makefile:

  1. Add pkg-config libkqueue --cflags to the CFLAGS variable.
  2. Add pkg-config libkqueue --libs to the LDADD variable.
  3. Add "#include <sys/event.h>" to the source code.

Autoconf/Automake/Libtool

If your program uses the GNU Autoconf/Automake/Libtool build system, the following steps will allow you to use libkqueue:

  1. Add the following to configure.ac:
            #
    # Prefer native kqueue(2); otherwise use libkqueue if present.
    #
    AC_CHECK_HEADER(sys/event.h, [],
      [PKG_CHECK_MODULES(KQUEUE, libkqueue)]
    )
    
  2. Add the following to Makefile.am (assuming your program is named "foo"):
            foo_CFLAGS+=$(KQUEUE_CFLAGS)
    foo_LDADD+=$(KQUEUE_LIBS)
    

Instead of using the $(KQUEUE_LIBS) variable, you could just add libkqueue.la to your programs LDADD variable.

Threads

libkqueue uses one or more helper threads, so all programs that link with libkqueue must also link against the pthreads library. Calls to kqueue() and kevent() are safe to be used from multiple threads.


Related

Wiki: Home