fix ENOBUFS errors with backoff+retry
This commit is contained in:
parent
ee414035de
commit
52ee2fd391
2 changed files with 23 additions and 11 deletions
|
|
@ -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)
|
||||
if (sent >= 0) {
|
||||
next += sent;
|
||||
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)
|
||||
}
|
||||
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 */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue