+
+ /* check if any callback are supposed to be removed */
+ for (cb = TAILQ_FIRST(&src->callbacks); cb != NULL; cb = next) {
+ next = TAILQ_NEXT(cb, next);
+ if (cb->pending_delete) {
+ /* remove it from the kqueue */
+ memset(&ke, 0, sizeof(ke));
+ /* mark for deletion from the queue */
+ ke.flags = EV_DELETE;
+
+ if (intr_source_to_kevent(&src->intr_handle, &ke) < 0) {
+ RTE_LOG(ERR, EAL, "Cannot convert to kevent\n");
+ rte_spinlock_unlock(&intr_lock);
+ return;
+ }
+
+ /**
+ * remove intr file descriptor from wait list.
+ */
+ if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0) {
+ RTE_LOG(ERR, EAL, "Error removing fd %d kevent, "
+ "%s\n", src->intr_handle.fd,
+ strerror(errno));
+ /* removing non-existent even is an expected
+ * condition in some circumstances
+ * (e.g. oneshot events).
+ */
+ }
+
+ TAILQ_REMOVE(&src->callbacks, cb, next);
+ if (cb->ucb_fn)
+ cb->ucb_fn(&src->intr_handle, cb->cb_arg);
+ free(cb);
+ }
+ }
+
+ /* all callbacks for that source are removed. */
+ if (TAILQ_EMPTY(&src->callbacks)) {
+ TAILQ_REMOVE(&intr_sources, src, next);
+ free(src);
+ }
+