Switch to empty structs for some signaling channels

This signals the semantic meaning of the payload of these channels
that only exist to synchronize rather than transmit data a little bit
better: wheres before there were two legitimate values (for Boolean
channels), there is now only one: the empty struct.

Signed-off-by: Daniel Farina <daniel@fdr.io>
Remove pointless blank-bindings

Channels don't need to use any bindings unblock when the other side is
closed.

Signed-off-by: Daniel Farina <daniel@fdr.io>
Fix resource leak; optimize

A bogus stat lock was causing goroutines to not exit in a timely
manner.  It's not entirely clear why things worked even semi-well
before.  This was exposed by moving the token-bucket grabbing from a
concurrent goroutine into the caller of BufferMessage, which can
prevent many short-lived goroutines that must be scheduled from ever
being born.

It seems like with this change that resident memory is stable.

Performance is about 10-20% slower in the synthetic benchmarks when
GOMAXPROCS=1 (no SMP parallelism or the interlocking that requires),
but is considerably faster in situations where channels require
interlock (GOMAXPROCS > 1), where the approach of eliminating channel
interactions at the cost of slowing down the synchronous part of
BufferMessages a little is more worthwhile.

Signed-off-by: Daniel Farina <daniel@fdr.io>