// Helper method to send a number of bytes over fd. Returns the
// number of bytes that failed to send.
int 
stream_handler::send_data(const char * buf, size_t length) {
   int bytes_written = write(fd, buf, length);
   if(bytes_written == -1) {
      if(errno == EAGAIN) {
         tracer.trace5( "EAGAIN when trying to write %zu bytes to fd%d", length, fd);
         // The file descriptor is backed up! Try again when it
         // becomes writeable in the future.
         watch_writable(fd, true);
         return length;
      }
      if(errno == ECONNRESET) {
         // Connection closed by the other side while we were
         // busy getting through our buf_.
         tracer.trace0( "Connection closed when trying to write %zu bytes to fd%d",
                        length, fd);
         on_connection_closed();
         watch_stream(fd, false);
         return 0;
      }
      tracer.trace0( "Unexpected error code from send(): %d", errno);
      assert("send unexpectedly failed");
   } else if((size_t) bytes_written < length) {
      watch_writable(fd, true);
   } else {
      // The fd is sending all data, no need to get alerts on when
      // it is writable.
      watch_writable(fd, false);
   }
   tracer.trace8("Sent %d of %zu bytes", bytes_written, length);
   return length - bytes_written;
}
void messaging_adapter::on_connection_remote_close(event &e) {
    proton_event *pe = dynamic_cast<proton_event*>(&e);
    if (pe) {
        pn_event_t *cevent = pe->pn_event();
        pn_connection_t *connection = pn_event_connection(cevent);
        pn_state_t state = pn_connection_state(connection);
        if (pn_condition_is_set(pn_connection_remote_condition(connection))) {
            messaging_event mevent(messaging_event::CONNECTION_ERROR, *pe);
            on_connection_error(mevent);
        }
        else if (is_local_closed(state)) {
            messaging_event mevent(messaging_event::CONNECTION_CLOSED, *pe);
            on_connection_closed(mevent);
        }
        else {
            messaging_event mevent(messaging_event::CONNECTION_CLOSING, *pe);
            on_connection_closing(mevent);
        }
        pn_connection_close(connection);
    }
}
void 
stream_handler::on_readable(int notifying_fd) {
   if(notifying_fd != fd) {
      return;
   }
   // Read as many bytes as we can off of the socket
   int bytes_recvd = recv(fd, read_buf + bytes_read,
                          buf_size - bytes_read, 0);
   if(bytes_recvd == -1) {
      tracer.trace0("Recv unexpectedly failed");
      return;
   }
   if(bytes_recvd == 0) {
      tracer.trace0("Connection to %d closed", fd);
      on_connection_closed();
      watch_stream(fd, false);
      return;
   }
   bytes_read += bytes_recvd;
   drain_read_buffer();
}