mux: Write: don't block holding the metadata mutex
mux: Write: don't block holding the metadata mutex

The metadata mux must only be held briefly while updating internal
state; we shouldn't block performing I/O on the network (which may
be contended).

Previously we could acquire the metadata mutex on channel 1, then
block waiting for the channel mutex. Meanwhile lots of other I/O
would keep the channel mutex busy and then a Window update message
could arrive, which would block on the metadata mutex. This would
cause the main receive goroutine to block, causing I/O to start
backing up on the remote. If all get out of control and ends up
deadlocking.

Now we drop the metadata mutex while waiting for the I/O one.

Signed-off-by: David Scott <63c9eb0ea83039690fefa11afe17873ba8278a56@docker.com>

djs55/vpnkit,djs55/vpnkit,djs55/vpnkit