static void log_writer_start_watches(LogWriter *self) { gint fd; GIOCondition cond; if (!self->watches_running) { log_proto_prepare(self->proto, &fd, &cond); if (self->pollable_state < 0) { if (is_file_regular(fd)) self->pollable_state = 0; else self->pollable_state = iv_fd_pollable(fd); } if (self->pollable_state) { self->fd_watch.fd = fd; iv_fd_register(&self->fd_watch); } log_writer_update_watches(self); self->watches_running = TRUE; } }
static void log_writer_start_watches(LogWriter *self) { gint fd; GIOCondition cond; if (self->watches_running) return; log_proto_client_prepare(self->proto, &fd, &cond); self->fd_watch.fd = fd; if (self->pollable_state < 0) { if (is_file_regular(fd)) self->pollable_state = 0; else self->pollable_state = !iv_fd_register_try(&self->fd_watch); } else if (self->pollable_state > 0) iv_fd_register(&self->fd_watch); log_writer_update_watches(self); self->watches_running = TRUE; }
static void log_writer_queue_filled(gpointer s) { LogWriter *self = (LogWriter *) s; main_loop_assert_main_thread(); /* * NOTE: This theory is somewhat questionable, e.g. I'm not 100% sure it * is the right scenario, but the race was closed. So take this with a * grain of salt. * * The queue_filled callback is running in the main thread. Because of the * possible delay caused by iv_event_post() the callback might be * delivered event after stop_watches() has been called. * * - log_writer_schedule_update_watches() is called by the reader * thread, which calls iv_event_post() * - the main thread calls stop_watches() in work_perform * - the event is delivered in the main thread * * But since stop/start watches always run in the main thread and we do * too, we can check if this is the case. A LogWriter without watches * running is busy writing out data to the destination, e.g. a * start_watches is to be expected once log_writer_work_finished() is run * at the end of the deferred work, executed by the I/O threads. */ if (self->watches_running) log_writer_update_watches((LogWriter *) s); }
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); }