CA-337546: use a single persistent pipe per scheduler, avoid using pipes in Delay.wait
CA-337546: use a single persistent pipe per scheduler, avoid using pipes in Delay.wait

Less chance of failure, and more predictable resource usage.
Now we only need 2 file descriptors per scheduler, instead of 2 file
descriptors for each active Delay.wait/signal call.

The method of adding a oneshot entry to the scheduler that wakes up the
condition variable's waiter is already used by Updates.get, and
xapi_event code.

Since pipes are open at PipeDelay.make () time we don't need to deal
with pre-signalling (calling .signal before .wait) explicitly:
signal will write a byte to the pipe, and wait will find it and not go
to sleep.
We also don't need a mutex for dealing with pipes.

We do need to deal with pre-signalling in the Delay code.
Also the old code didn't handle spurious wakeups from Condition.wait.
According to the POSIX manpage for pthread_cond_wait it can spuriously
wake up for any reason, so you're meant to check that you achieved the
condition you were waiting for a in a loop to be robust.
(the Linux manpage doesn't mention this though).
Be more robust and handle spurious wakeups and pre-signalling in one go:
we explicitly set our state to Signalled while holding a mutex, and
explicitly set our state to TimedOut from the oneshot handler.
That way we can loop until either of these is set and spurious wakeups
or not guarantee we only exit the loop when one of these is true.

Ideally we would've used `pthread_cond_timedwait` instead of all of
this, but that is not available in the OCaml standard library
and writing a C binding would need to duplicate the mutex/condition
bindings too since those cannot be accessed from a C binding: the
headers implementing them are private.

Signed-off-by: Edwin Török <c8d178016cbaf8a6ef23c2cbc9db96123c48b7dc@citrix.com>

xapi-project/message-switch,xapi-project/message-switch,xapi-project/message-switch