'Sends a message to our control socket and provides back its reply.
:param str message: message to be formatted and sent to tor
:returns: :class:`~stem.response.ControlMessage` with the response
:raises:
* :class:`stem.ProtocolError` the content from the socket is
malformed
* :class:`stem.SocketError` if a problem arises in using the
socket
* :class:`stem.SocketClosed` if the socket is shut down'

def msg(self, message):

    with self._msg_lock:
        while (not self._reply_queue.empty()):
            try:
                response = self._reply_queue.get_nowait()
                if isinstance(response, stem.SocketClosed):
                    pass
                elif isinstance(response, stem.ProtocolError):
                    log.info(('Tor    provided    a    malformed    message    (%s)' % response))
                elif isinstance(response, stem.ControllerError):
                    log.info(('Socket    experienced    a    problem    (%s)' % response))
                elif isinstance(response, stem.response.ControlMessage):
                    log.info(('Failed    to    deliver    a    response:    %s' % response))
            except queue.Empty:
                break
        try:
            self._socket.send(message)
            response = self._reply_queue.get()
            if isinstance(response, stem.ControllerError):
                raise response
            else:
                if message.upper().startswith('AUTHENTICATE'):
                    self._post_authentication()
                return response
        except stem.SocketClosed as exc:
            self.close()
            raise exc
