Async Timeout
This timeout uses a background thread to take action exactly when the timeout occurs. Use this to implement timeouts where they aren't supported natively, such as to sockets that are blocked on writing.
Subclasses should override timedOut to take action when a timeout occurs. This method will be invoked by the shared watchdog thread so it should not do any long-running operations. Otherwise we risk starving other timeouts from being triggered.
Use sink and source to apply this timeout to a stream. The returned value will apply the timeout to each operation on the wrapped stream.
Callers should call enter before doing work that is subject to timeouts, and exit afterwards. The return value of exit indicates whether a timeout was triggered. Note that the call to timedOut is asynchronous, and may be called after exit.