thread_pool: fix synchronization when checking if a task is being used in #<<

The current code was testing against started? without taking any
mutex. This had two flaws: it was possible to queue the same
task twice -- probably with bad consequences -- and it was
possible for a task to be started between the check and the
queueing.

This replaces the reset method by an acquire method. Acquire
both sets the queued_at attribute *and* checks whether the task
is already in use or not within the same mutex, ensuring proper
synchronization.
event_loop: propagate the backtrace of the original exception when modifying it in the callback

Callbacks can return an exception object to override the error raised
by the work block. However, setting the backtrace of that exception
object is awkward, and will probably be forgotten most of the time.

Make sure that, if no backtrace has been provided, we propagate the
backtrace of the original exception into the new one.
event_loop: implement EventLoop#process_all_pending_work

Unless #step and #steps, it will return only when all work is
finished, including (optionally) all currently running threads.

This will be used to refactor testing in EventLoop the same way
the ThreadPool tests got refactored (i.e. remove all sleep()).
However, it might also be a better alternative than step in e.g.
vizkit as it removes latency in processes that require multiple
events.
event_loop: major refactoring of the test suite

The spirit of this refactoring is to remove all need to sleep()
by either mocking Time.now (see the mock_time* helpers) or by
using the newly added thread pool synchronization methods (see
EventLoop#process_all_async_work)

It is also to move to something closer to "best practice" in spec
writing (smaller specs, move common setup code to before/end/let,
remove of 'must' and 'can' from spec wording ...)
event_loop: fix callback block being passed as block to deferred method

In Forward.def_event_loop_delegator, the async case (i.e. method
calles with a block) was interpreting the block both as callback
and as a block that should be passed to the underlying method.

Given the usage in vizkit, I guessed that the second use was not
intended
event_loop: provide an API to call a timer synchronously

It changed ThreadPool#sync to accept nil sync keys for consistency
reasons.
event_loop: fix delayed once blocks

Timer#start's second argument by default queues the timer work
for the next call to #step. However, for a delayed work block,
it really mean that we just ignore the delay.
event_loop: add the queue option to async and periodic calls

It controls whether the work should be queued right away, or if it
should either wait for a period (in the periodic every and
async_every calls) or be explicitly queued (in defer).

In addition, in async_every, it creates the thread pool task right
away so that it is available for the caller to manipulate (and e.g.
execute explicitely with #execute). This removes a delay in queueing
the work as we don't wait for #step to be called to feed the work
to the thread pool.
event_loop: remove unneeded synchronization

ThreadPool#<< is already thread-safe
event_loop: accept any filter object in #on_error
event_loop: make Forward raise right away if the accessor is not available even in the deferred case

Until now, a deferred method call would not check for the availability
of the accessor when the call is queued, only when it is made. However,
since there is virtually no way of reliably setting the accessor in
between, also do the check early. The late check is kept for safety
reasons (as it *is* possible to unreliably set it ;-))
event_loop: add some synchronization API

This is mostly useful for tests, but can also be in some cases
of interaction between async and non-async APIs
event_loop: change style from hash to keyword arguments
event_loop: add some primitive tracing-to-logger facility
event_loop: make wait_for use process_all_pending_work

This makes sure that wait_for really tries to execute as fast
as possible.
event_loop: simplify Timer#timeout?
event_loop: explicitly reset the timer in Timer#execute
event_loop: implement Timer#queue

Unlike Timer#execute, which executes the task in the caller's
thread, this simply explicitly queues the work in the thread
pool and optionally resets the timer.
event_loop: un-hide the use of Time.now a bit more
event_loop: refactor step into smaller processing methods

This clarifies the step processing by splitting the code in smaller
steps.

It also removes the @number_of_events_to_process mechanism as IMO
it lost its purpose: either @number_of_events_to_process was greater
than @queue.size and it would block, or it is smaller and therefore
useless. Since the blocking behaviour is definitely unwanted, its
only purpose was to count processed events so that we don't process
newly queued events. This is handled by a boolean parameter to
process_events