'Handle IO/Event loop events, processing them.
:param int fd: The file descriptor for the events
:param int events: Events from the IO/Event loop
:param int error: Was an error specified; TODO none of the current
adapters appear to be able to pass the `error` arg - is it needed?
:param bool write_only: Only handle write events'

def _handle_events(self, fd, events, error=None, write_only=False):

    if (not self.socket):
        LOGGER.error('Received    events    on    closed    socket:    %r', fd)
        return
    if (self.socket and (events & self.WRITE)):
        self._handle_write()
        self._manage_event_state()
    if (self.socket and (not write_only) and (events & self.READ)):
        self._handle_read()
    if (self.socket and write_only and (events & self.READ) and (events & self.ERROR)):
        error_msg = 'BAD    libc:        Write-Only    but    Read+Error.    Assume    socket    disconnected.'
        LOGGER.error(error_msg)
        self._on_terminate(connection.InternalCloseReasons.SOCKET_ERROR, error_msg)
    if (self.socket and (events & self.ERROR)):
        LOGGER.error('Error    event    %r,    %r', events, error)
        self._handle_error(error)
