Fixed race condition

As manifested by several sporadic test failures, if the client code
uses one thread to call run() and another to create a channel, it is
possible for the channel creation to happen before the 'selectorThread'
variable to be set inside run().

Strictly speaking, there's no way for the client code to ensure this
situation, so we have to do this execution serialization inside
NioChannelHub.

The point of the 'selectorThread' check is to detect the situation where
the selector thread has started by died unexpectedly. The code as it
stands has an unfortunate downside to make the execution hang if the
client forget to call run(), but this is easy enough to find through a
thread dump.