diff --git a/new.c b/pixelflut.c similarity index 92% rename from new.c rename to pixelflut.c index d692747..1a8b2e6 100644 --- a/new.c +++ b/pixelflut.c @@ -216,18 +216,30 @@ static void *worker_main(void *arg) while (next < PACKET_COUNT) { int sent = sendmmsg(fd, &messages[next], (unsigned int)(PACKET_COUNT - next), 0); - if (sent == -1) { - if (errno == EINTR) - continue; - /* ECONNREFUSED is stale ICMP feedback on a connected - * UDP socket; EAGAIN means the send buffer is full. - * Both are transient - repaint and keep sending. */ - if (errno != ECONNREFUSED && errno != EAGAIN && - errno != EWOULDBLOCK) - perror("sendmmsg"); + if (sent >= 0) { + next += sent; + continue; + } + switch (errno) { + case EINTR: + continue; /* interrupted before sending - retry now */ + case ENOBUFS: /* interface send queue full: we outrun the link */ + case EAGAIN: +#if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + /* Transient back-pressure. Back off briefly so the queue + * drains (rather than spinning on failing syscalls), then + * resend the same batch - no need to repaint. */ + usleep(200); + continue; + case ECONNREFUSED: + break; /* stale ICMP on connected UDP; repaint and retry */ + default: + perror("sendmmsg"); break; } - next += sent; + break; /* ECONNREFUSED / unexpected: stop, repaint, retry */ } } diff --git a/pixelflut.h b/pixelflut.h index 99ef224..638a0ba 100644 --- a/pixelflut.h +++ b/pixelflut.h @@ -26,7 +26,7 @@ * to avoid IP fragmentation (e.g. 207 pixels ~= 1451 B fits a 1500 B link). * Override at build time with -DPIXELS_PER_PACKET=N. */ #ifndef PIXELS_PER_PACKET -# define PIXELS_PER_PACKET 120 +# define PIXELS_PER_PACKET 200 #endif #pragma pack(push, 1)