static void plugin_write_cb(struct ev_loop* loop, ev_io* w, int revents V_UNUSED) { dmn_assert(loop); dmn_assert(w); dmn_assert(revents == EV_WRITE); dmn_assert(plugin_write_fd > -1); while(!sendq_empty()) { const uint32_t data = sendq_deq_peek(); ssize_t write_rv = write(plugin_write_fd, &data, 4); if(write_rv != 4) { if(write_rv < 0) { if(errno == EAGAIN || errno == EWOULDBLOCK) return; // pipe full, wait for more libev notification of write-ready else if(errno == EINTR) continue; // try this write again immediately else { ev_break(loop, EVBREAK_ALL); return; } } else if(write_rv == 0) { ev_break(loop, EVBREAK_ALL); return; } else { log_fatal("BUG: atomic pipe write of 4 bytes was not atomic, retval was %zi", write_rv); } } sendq_deq_commit(); } ev_io_stop(loop, w); // queue now empty if(killed_by) { // we've sent our final message, close close(plugin_write_fd); plugin_write_fd = -1; } }
static void plugin_write_cb(struct ev_loop* loop, ev_io* w, int revents V_UNUSED) { dmn_assert(loop); dmn_assert(w); dmn_assert(revents == EV_WRITE); while(!sendq_empty()) { const uint32_t data = sendq_deq_peek(); int rv = write(plugin_write_fd, &data, 4); if(rv != 4) { if(rv < 0) { if(errno == EAGAIN) return; // pipe full, wait for more libev notification of write-ready else if(errno == EINTR) continue; // try this write again immediately else { ev_break(loop, EVBREAK_ALL); return; } } else if(rv == 0) { ev_break(loop, EVBREAK_ALL); return; } else { log_fatal("BUG: atomic pipe write of 4 bytes was not atomic, retval was %u", rv); } } sendq_deq_commit(); } ev_io_stop(loop, w); // queue now empty }
static void sendq_deq_commit(void) { dmn_assert(!sendq_empty()); sendq_head++; sendq_head &= (sendq_alloc - 1); sendq_len--; }
static uint32_t sendq_deq_peek(void) { dmn_assert(!sendq_empty()); return sendq[sendq_head]; }