kqueue: Initialize num to zero in iv_kqueue_notify_fd_sync().

We would forget to initialize this variable, causing all sorts of
mayhem when trying to use iv_fd_register_try() on kqueue.

Reported-by: Gergely Nagy <algernon@balabit.hu>
Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
dev_poll: Simplify iv_dev_poll_notify_fd_sync().

Considering that, on entry, fd->list_notify will always be
initialized, and fd->registered_bands will always be zero.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Work around iv_fd_register_try() being called without handlers.

iv_fd_register_try() was originally implemented so that it would
immediately perform any kernel registrations that it would have had to
perform anyway in the non-synchronous (iv_fd_register()) case.

Meaning that if you would call iv_fd_register_try() on an iv_fd that
has all handlers set to NULL, you would, on most poll methods, get a
success return regardless of the pollability of the file descriptor
you are passing in, since there will be no kernel event registration
done, and thus there is nothing that can return an error.

Having thought about it for a bit, I decided that the current implicit
"you must only call iv_fd_register_try() with at least one non-NULL
handler for the result to be reliable" rule is not a fair one, as it
violates the principle of least surprise.

Therefore, this commit adds some logic to detect the situation where
an fd is passed in that has all handlers set to NULL, and if that is
the case, register it with MASKIN | MASKOUT with the kernel instead.
If that fails, we return an error as usual, while if it succeeds, we
make a note to re-register the fd with the kernel again later, with
the originally intended (null) event mask.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_wait: Fix potential memory leak introduced by fairness changes.

If an iv_wait_interest is unregistered from its handler callback,
we would fail to free the memory corresponding to any wait events
that were still queued on this pid.

Fix this by always walking the entire pending event list in
iv_wait_completion(), even if we get unregistered halfway through,
as we will just not deliver the events then (but we'll still free
them).

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Bump version number to 0.31.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_event: Add iv_event_is_active().

Add iv_event_is_active(), which will tell you whether a struct
iv_event object is currently scheduled for execution.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_work: Get rid of work_pool_thread::kicked.

As the same information can be obtained by calling
iv_event_is_active() on the 'struct iv_event kick' member.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_work: Slight optimization for race condition fix.

Instead of doing work in the worker threads directly from the
handler for the iv_event that is used by the main thread to signal a
worker thread, have the iv_event handler schedule an iv_task and do
the work from that iv_task.

The advantage of this is that if we want to quit the work handling
loop because of fairness reasons, and want to have ourselves
rescheduled at some point soon, we can do that by re-registering
our iv_task, which is just a linked list add, and cheaper than an
iv_event_post(), which is a lock/unlock and possibly a linked list
add plus a system call.

To shrink the state space for the various struct work_pool_thread
members, we also introduce the following invariant:

	iv_list_empty(&thr->list) <=>
		iv_task_registered(&thr->work_task) <=>
		!iv_timer_registered(&thr->idle_timer)

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
kqueue: Check for EV_ERROR on kevent() return.

Check for EV_ERROR in the flags fields of events returned by kevent(),
as that indicates a fatal error that we should report via iv_fatal().

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>