Example #1
0
// 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;
}
Example #2
0
void SessionHandler::WatchStream(int socketDescriptor, bool doWatch)
{
    assert((m_fd != 0 && m_fd != socketDescriptor) == false); // only one stream for a socket

    if (doWatch)
    {
        m_tracer.trace0("watching socket %d", socketDescriptor);

        m_fd = socketDescriptor;
        watch_readable(m_fd, true);

        m_readBuffer = new char[m_bufferSize];
        m_writeBuffer = new char[m_bufferSize];
        m_bytesRead = 0;
        m_bytesToWrite = 0;
        OnConnect();
    }
    else if (m_fd != 0)
    {
        m_tracer.trace0("cleaning up");

        watch_readable(m_fd, false);
        watch_writable(m_fd, false);
        delete [] m_readBuffer;
        delete [] m_writeBuffer;
        m_readBuffer = nullptr;
        m_writeBuffer = nullptr;
        m_fd = 0;
        m_nextMessageLength = 0;
    }
}
Example #3
0
void 
stream_handler::watch_stream(int file_descriptor, bool should_watch) {
   if(fd && fd != file_descriptor) {
      assert(!"Only allowed to handle one stream at a time");
   }
   if(!should_watch) {
      if(fd) {
         tracer.trace0("Cleaning up");
         watch_readable(fd, false);
         watch_writable(fd, false);
         delete[] read_buf;
         delete[] write_buf;
         read_buf = NULL;
         write_buf = NULL;
         fd = 0;
         next_message_length = 0;
         delimiter = NULL;
         delimiter_length = 0;
      }
   } else {
      tracer.trace0("Watching stream %d", file_descriptor);
      fd = file_descriptor;
      watch_readable(fd, true);
      read_buf = new char[buf_size];
      write_buf = new char[buf_size];
      bytes_read = 0;
      bytes_to_write = 0;
   }
}
Example #4
0
int SessionHandler::SendData(const char* buffer, size_t length)
{
    auto bytesWritten = write(m_fd, buffer, length);

    if (bytesWritten == -1)
    {
        switch (errno)
        {
            case EAGAIN:
                m_tracer.trace5("EAGAIN when trying %d bytes to socket %d", length, m_fd);
                watch_writable(m_fd, true);
                return length;

            case ECONNRESET:
                m_tracer.trace0("connection closed while trying to write %d bytes to %d",
                                length, m_fd);

                OnConnectionClosed();
                WatchStream(m_fd, false);
                return 0;

            default:
                m_tracer.trace0("unexpected error code from send(): %d", errno);
                break;
        }
    }
    else if ((size_t)bytesWritten < length)
    {
        watch_writable(m_fd, true);
    }
    else
    {
        watch_writable(m_fd, false);
    }

    return length - bytesWritten;
}
Example #5
0
void
stream_handler::on_writable(int notifying_fd) {
   if(notifying_fd != fd) {
      return;
   }
   if(!bytes_to_write) {
      // If we somehow get called but have nothing to write,
      // unregister our interest in this notification.
      watch_writable(fd, false);
      return;
   }
   tracer.trace7("Buffer is writable, attempting to send %zu bytes",
                 bytes_to_write);
   int bytes_remaining = send_data(write_buf, bytes_to_write);
   if(bytes_remaining) {
      memmove(write_buf, write_buf + bytes_to_write - bytes_remaining,
              bytes_remaining);
   }
   bytes_to_write = bytes_remaining;
}
Example #6
0
void SessionHandler::on_writable(int notifyingSocket)
{
   if (notifyingSocket != m_fd)
   {
      return;
   }

   if (m_bytesToWrite == 0)
   {
      watch_writable(m_fd, false);
      return;
   }

   m_tracer.trace7("Buffer is writable, attempting to send %d bytes", m_bytesToWrite);

   auto bytesRemaining = SendData(m_writeBuffer, m_bytesToWrite);

   if(bytesRemaining)
   {
      memmove(m_writeBuffer, m_writeBuffer + m_bytesToWrite - bytesRemaining, bytesRemaining);
   }

   m_bytesToWrite = bytesRemaining;
}