static gboolean log_writer_fd_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { LogWriterWatch *self = (LogWriterWatch *) source; gint64 num_elements = log_queue_get_length(self->writer->queue); if (self->pollfd.revents & (G_IO_HUP | G_IO_IN) && self->input_means_connection_broken) { msg_error("EOF occurred while idle", evt_tag_int("fd", log_proto_get_fd(self->proto)), NULL); log_writer_broken(self->writer, NC_CLOSE); return FALSE; } else if (self->pollfd.revents & (G_IO_ERR) && num_elements == 0) { msg_error("POLLERR occurred while idle", evt_tag_int("fd", log_proto_get_fd(self->proto)), NULL); log_writer_broken(self->writer, NC_WRITE_ERROR); } else if (num_elements) { if (!log_writer_flush_log(self->writer, self->proto)) { self->error_suspend = TRUE; g_source_get_current_time(source, &self->error_suspend_target); g_time_val_add(&self->error_suspend_target, self->writer->options->time_reopen * 1e6); log_writer_broken(self->writer, NC_WRITE_ERROR); if (self->writer->source == (GSource *) self) { msg_notice("Suspending write operation because of an I/O error", evt_tag_int("fd", log_proto_get_fd(self->proto)), evt_tag_int("time_reopen", self->writer->options->time_reopen), NULL); } return TRUE; } } return TRUE; }
static void log_writer_io_check_eof(gpointer s) { LogWriter *self = (LogWriter *) s; msg_error("EOF occurred while idle", evt_tag_int("fd", log_proto_client_get_fd(self->proto))); log_writer_broken(self, NC_CLOSE); }
static void log_writer_work_finished(gpointer s) { LogWriter *self = (LogWriter *) s; main_loop_assert_main_thread(); self->flush_waiting_for_timeout = FALSE; if (self->pending_proto_present) { /* pending proto is only set in the main thread, so no need to * lock it before coming here. After we're syncing with the * log_writer_reopen() call, quite possibly coming from a * non-main thread. */ g_static_mutex_lock(&self->pending_proto_lock); if (self->proto) log_proto_free(self->proto); self->proto = self->pending_proto; self->pending_proto = NULL; self->pending_proto_present = FALSE; g_cond_signal(self->pending_proto_cond); g_static_mutex_unlock(&self->pending_proto_lock); } if (!self->work_result) { log_writer_broken(self, NC_WRITE_ERROR); if (self->proto) { log_writer_suspend(self); msg_notice("Suspending write operation because of an I/O error", evt_tag_int("fd", log_proto_get_fd(self->proto)), evt_tag_int("time_reopen", self->options->time_reopen), NULL); } goto exit; } if ((self->super.flags & PIF_INITIALIZED) && self->proto) { /* reenable polling the source, but only if we're still initialized */ log_writer_start_watches(self); } exit: log_pipe_unref(&self->super); }
static void log_writer_io_error(gpointer s) { LogWriter *self = (LogWriter *) s; if (self->fd_watch.handler_out == NULL && self->fd_watch.handler_in == NULL) { msg_debug("POLLERR occurred while idle", evt_tag_int("fd", log_proto_client_get_fd(self->proto))); log_writer_broken(self, NC_WRITE_ERROR); return; } else { /* in case we have an error state but we also asked for read/write * polling, the error should be handled by the I/O callback. But we * need not call that explicitly as ivykis does that for us. */ } log_writer_update_watches(self); }