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(); }
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; }
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(); }
/* 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; }
/* 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; }