Use asynchronous reading from the debugger pipe

Previously the debugger listener thread would block for 100 ms between
reads of debugger pipe. The issue was 99% of the time there is no data
to receive so the thread would block.

Any operation that then actually required receiving data from the
debugger would incur a delay due to the blocked thread. The small delay
between reads of the pipe added up to a significant pause between
operations when debugging code.

We now read from the pipe asynchronously (non-blocking) so the debugger
communication is much faster.

An additional improvement would be to remove the dedicated listener
thread as this probably isn't required now that the reading is
asynchronous.

The error handling hasn’t been tested.