iv_signal: Implement spinlocks by hand if pthread_spin_lock() unavailable.

Some platforms (such as OpenBSD 5.1) don't provide an implementation
of pthread_spin_lock() and friends, in which case we implement spinlocks
by hand, using gcc's __sync_*() intrinsics.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_inotify: Only install man pages if inotify support was detected.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_wait: Handle caller unregistration differently.

Perform detection of unregistration of the calling context via a
thread-local variable.  Aside from being cleaner, this also makes
the 'warning: dereferencing type-punned pointer will break
strict-aliasing rules' warning that we'd get on some platforms go
away.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
select: Save some space in struct iv_state.

As three of the four fd_set pointers stored in there can easily be
computed from the others.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Introduce iv_fatal(), and route all fatal error conditions through it.

When ivykis detects a fatal error, we shouldn't unconditionally log
the error message to syslog like we do right now.

This commit introduces iv_fatal(), which is a printf-style varargs
function that takes a message for a fatal error, formats it, logs it,
and then aborts the current process.

By default, the message will be logged to syslog as before, unless
iv_set_fatal_msg_handler() was used to set up an alternative error
message log function, in which case it will be logged to that function
instead.

(Original idea from the Balabit ivykis tree.  Suggestion for marking
iv_fatal() with __attribute__((format(printf, 1, 2))) from Gergely
Nagy <algernon@balabit.hu>.)

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_fatal: Add a manual page and an example.

This is a little manual page for iv_fatal(3), and a trivial example
for it in iv_examples(3).  While we're at it, remove direct use of
syslog(2) in iv_examples(3), as that is now deprecated.

Signed-off-by: Gergely Nagy <algernon@balabit.hu>
Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Pass in iv_poll_method::poll() timeout argument as a struct timespec.

Instead of converting the struct timespec that we get from
iv_get_soonest_timeout() into a millisecond count that some poll
methods then convert back to a struct timespec again.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
configure.ac: Don't test for stdint.h.

As we don't use it anywhere.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Introduce __iv_list_steal_elements().

For moving all elements on a list to another list, to be used for
enforcing fairness in various parts of ivykis.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_task: Implement fairness by list splicing.

When iv_run_tasks() is called, we want it to only process tasks that
were registered before the function was called.  This is currently
done by inserting a sentinel element, but it's easier to just move
all tasks to a local list on entry to the function and then work off
the local list.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_event: Implement fairness by list splicing.

When iv_event_run_pending_events() is called, we want it to only
process events that were active before the function was called.  This
is currently done by inserting a sentinel element, but it's easier to
just move all events to a local list on entry to the function and
then work off the local list.  This simplifies the locking as well.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_wait: Implement fairness by list splicing.

When iv_wait_completion() is called, we want it to only process wait
events that were queued before the function was called.  We'll do
this in the same way as iv_task and iv_event do, by moving all wait
events to a local list on entry to the function and then working off
the local list.  This simplifies the locking as well.  If we exit
the function with wait events pending, iv_event guarantees that we'll
be called again at a later time.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_work: Implement fairness for thread work items using sequence numbers.

When iv_work_thread_got_event() is called, we want it to only process
work items that were registered before the function was called.

We can't do this by moving all work items to a local list like it
is done elsewhere in ivykis, since the list of pending work items
is shared between all threads in the thread pool, and so this would
starve other threads of work.

What we can do instead is to (virtually) assign each work item a
sequence number at enqueue time, and when it's time to process work
items, only process work items that have a sequence number less than
or equal to the sequence number of the last work item on the list
when we entered this thread's work processing function.

If we exit iv_work_thread_got_event() with work items pending,
iv_event guarantees that we'll be called again at a later time.

To make things slightly more efficient, we'll make a small change to
the handling of the idle thread list and the idle timer: if we exit
iv_work_thread_got_event() with work items pending, we won't re-add
ourselves to the list of idle threads, and we won't restart the idle
timer.  We'll detect this condition in the next call of the function
by checking whether thr->list is on a list, and if not, we'll skip
deleting ourselves from the list of idle threads and stopping the
idle timer on entry.

The idea of thread work item fairness was taken from the Balabit
ivykis tree, but this implementation is entirely different.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_work: Implement fairness for completion handlers by list splicing.

When iv_work_event() is called, we want it to only invoke work item
completion callbacks for work items that completed before the function
was called.  We'll do this in the (by now) usual way, by moving all
completed work items to a local list on entry to the function and then
working off the local list.  This simplifies the locking as well.  If
we exit the function with completed work items pending, iv_event
guarantees that we'll be called again at a later time.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
iv_work: Implement fairness for local work items by list splicing.

When iv_work_handle_local() is called, we want it to only process
work items that were registered before the function was called.  We'll
do this in the (by now) usual way, by moving all work items to a local
list on entry to the function and then working off the local list.  If
we exit the function with work items pending, iv_task guarantees that
we'll be called again at a later time.

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