Пример #1
0
void
assert_proto_server_fetch_single_read(LogProtoServer *proto, const gchar *expected_msg, gssize expected_msg_len)
{
    const guchar *msg = NULL;
    gsize msg_len = 0;
    LogProtoStatus status;
    LogTransportAuxData aux;
    Bookmark bookmark;
    gboolean may_read = TRUE;

    start_grabbing_messages();
    log_transport_aux_data_init(&aux);
    status = log_proto_server_fetch(proto, &msg, &msg_len, &may_read, &aux, &bookmark);
    assert_proto_server_status(proto, status, LPS_SUCCESS);

    if (expected_msg)
    {
        assert_nstring((const gchar *) msg, msg_len, expected_msg, expected_msg_len, "LogProtoServer expected message mismatch");
    }
    else
    {
        assert_true(msg == NULL, "when single-read finds an incomplete message, msg must be NULL");
        assert_true(aux.peer_addr == NULL, "returned saddr must be NULL on success");
    }
    stop_grabbing_messages();
}
Пример #2
0
LogProtoStatus
proto_server_fetch(LogProtoServer *proto, const guchar **msg, gsize *msg_len)
{
    Bookmark bookmark;
    LogTransportAuxData aux;
    GSockAddr *saddr;
    gboolean may_read = TRUE;
    LogProtoStatus status;

    start_grabbing_messages();
    do
    {
        log_transport_aux_data_init(&aux);
        status = log_proto_server_fetch(proto, msg, msg_len, &may_read, &aux, &bookmark);
    }
    while (status == LPS_SUCCESS && *msg == NULL && may_read);

    saddr = aux.peer_addr;
    if (status == LPS_SUCCESS)
    {
        g_sockaddr_unref(saddr);
    }
    else
    {
        assert_true(saddr == NULL, "returned saddr must be NULL on failure");
    }
    stop_grabbing_messages();
    return status;
}
Пример #3
0
void
assert_proto_server_fetch_ignored_eof(LogProtoServer *proto)
{
  const guchar *msg = NULL;
  gsize msg_len = 0;
  LogProtoStatus status;
  LogTransportAuxData aux;
  gboolean may_read = TRUE;

  start_grabbing_messages();
  log_transport_aux_data_init(&aux);
  status = log_proto_server_fetch(proto, &msg, &msg_len, &may_read, &aux);
  assert_proto_server_status(proto, status, LPS_SUCCESS);
  assert_true(msg == NULL, "when an EOF is ignored msg must be NULL");
  assert_true(aux.peer_addr == NULL, "returned saddr must be NULL on success");
  stop_grabbing_messages();
}
Пример #4
0
/* returns: notify_code (NC_XXXX) or 0 for success */
static gint
log_reader_fetch_log(LogReader *self)
{
  gint msg_count = 0;
  gboolean may_read = TRUE;
  LogTransportAuxData aux;

  log_transport_aux_data_init(&aux);
  if (log_proto_server_handshake_in_progress(self->proto))
    {
      return log_reader_process_handshake(self);
    }

  /* NOTE: this loop is here to decrease the load on the main loop, we try
   * to fetch a couple of messages in a single run (but only up to
   * fetch_limit).
   */
  while (msg_count < self->options->fetch_limit && !main_loop_worker_job_quit())
    {
      Bookmark *bookmark;
      const guchar *msg;
      gsize msg_len;
      LogProtoStatus status;

      msg = NULL;

      /* NOTE: may_read is used to implement multi-read checking. It
       * is initialized to TRUE to indicate that the protocol is
       * allowed to issue a read(). If multi-read is disallowed in the
       * protocol, it resets may_read to FALSE after the first read was issued.
       */

      log_transport_aux_data_reinit(&aux);
      bookmark = ack_tracker_request_bookmark(self->super.ack_tracker);
      status = log_proto_server_fetch(self->proto, &msg, &msg_len, &may_read, &aux, bookmark);
      switch (status)
        {
        case LPS_EOF:
          g_sockaddr_unref(aux.peer_addr);
          return NC_CLOSE;
        case LPS_ERROR:
          g_sockaddr_unref(aux.peer_addr);
          return NC_READ_ERROR;
        case LPS_SUCCESS:
          break;
        default:
          g_assert_not_reached();
          break;
        }

      if (!msg)
        {
          /* no more messages for now */
          break;
        }
      if (msg_len > 0 || (self->options->flags & LR_EMPTY_LINES))
        {
          msg_count++;

          ScratchBuffersMarker mark;
          scratch_buffers_mark(&mark);
          if (!log_reader_handle_line(self, msg, msg_len, &aux))
            {
              scratch_buffers_reclaim_marked(mark);
              /* window is full, don't generate further messages */
              break;
            }
          scratch_buffers_reclaim_marked(mark);
        }
    }
  log_transport_aux_data_destroy(&aux);

  if (msg_count == self->options->fetch_limit)
    self->immediate_check = TRUE;
  return 0;
}
Пример #5
0
/* returns: notify_code (NC_XXXX) or 0 for success */
static gint
log_reader_fetch_log(LogReader *self)
{
  GSockAddr *sa;
  gint msg_count = 0;
  gboolean may_read = TRUE;

  if (self->waiting_for_preemption)
    may_read = FALSE;

  /* NOTE: this loop is here to decrease the load on the main loop, we try
   * to fetch a couple of messages in a single run (but only up to
   * fetch_limit).
   */
  while (msg_count < self->options->fetch_limit && !main_loop_io_worker_job_quit())
    {
      const guchar *msg;
      gsize msg_len;
      LogProtoStatus status;

      msg = NULL;
      sa = NULL;

      /* NOTE: may_read is used to implement multi-read checking. It
       * is initialized to TRUE to indicate that the protocol is
       * allowed to issue a read(). If multi-read is disallowed in the
       * protocol, it resets may_read to FALSE after the first read was issued.
       */

      status = log_proto_server_fetch(self->proto, &msg, &msg_len, &sa, &may_read);
      switch (status)
        {
        case LPS_EOF:
        case LPS_ERROR:
          g_sockaddr_unref(sa);
          return status == LPS_ERROR ? NC_READ_ERROR : NC_CLOSE;
        case LPS_SUCCESS:
          break;
        default:
          g_assert_not_reached();
          break;
        }

      if (!msg)
        {
          /* no more messages for now */
          break;
        }
      if (msg_len > 0 || (self->options->flags & LR_EMPTY_LINES))
        {
          msg_count++;

          if (!log_reader_handle_line(self, msg, msg_len, sa))
            {
              /* window is full, don't generate further messages */
              log_proto_server_queued(self->proto);
              g_sockaddr_unref(sa);
              break;
            }
        }
      log_proto_server_queued(self->proto);
      g_sockaddr_unref(sa);
    }
  if (self->options->flags & LR_PREEMPT)
    {
      if (log_proto_server_is_preemptable(self->proto))
        {
          self->waiting_for_preemption = FALSE;
          log_pipe_notify(self->control, &self->super.super, NC_FILE_SKIP, self);
        }
      else
        {
          self->waiting_for_preemption = TRUE;
        }
    }
  if (msg_count == self->options->fetch_limit)
    self->immediate_check = TRUE;
  return 0;
}