When an event is logged with a kqueue identifier, the type associated with this event is supplied; for example a file descriptor is used to identify the file to look
int kq; struct kevent ke; kq = kqueue(); fd = open(argv[1], O_RDONLY); EV_SET(&ke, fd, EVFILT_VNODE, EV_ADD, NOTE_DELETE | NOTE_RENAME, 0, NULL); kevent(kq, &ke, 1, NULL, 0, NULL); while (1) { kevent(kq, NULL, 0, &ke, 1, NULL); }
Now, if I also need to respond to other types of events, such signals, we need a new instance of kqueue to avoid conflict with the ident kevent() argument.
kq_sig = kqueue(); struct kevent ke_sig; signal(SIGINT, SIG_IGN); EV_SET(&ke_sig, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); kevent(kq_sig, &ke_sig, 1, NULL, 0, NULL); while (1) { kevent(kq_sig, NULL, 0, &ke_sig, 1, NULL); }
Observing several types of events requires several threads that act in general condition (receiving a signal may close the file descriptor for example).
Is there a more general mechanism for sending messages from one thread to another using Kqueue? In some cases, I can imagine turning the filter on and off as a means to trigger the edge of another cement.