Improve disconnect and shutdown handling.

Previously the exported Disconnect and Shutdown functions called each other
and therefore needed to release and reacquire the locks which could
potentionally allow a request to sneak in between the lock and unlock.

This commit changes the exported Shutdown function so that everything is
done under the request lock to prevent this possibility.  In order to
support this, the shared code between the Disconnect and Shutdown
functions has been refactored into unexported functions and the locking
has been altered accordingly.

Also, replace the sendMessage function with a select over the send and
disconnect channels to prevent any issues with queued up messages.

joint debugging effort between myself and @jrick