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) {
|
while (next < PACKET_COUNT) {
|
||||||
int sent = sendmmsg(fd, &messages[next],
|
int sent = sendmmsg(fd, &messages[next],
|
||||||
(unsigned int)(PACKET_COUNT - next), 0);
|
(unsigned int)(PACKET_COUNT - next), 0);
|
||||||
if (sent == -1) {
|
if (sent >= 0) {
|
||||||
if (errno == EINTR)
|
next += sent;
|
||||||
continue;
|
continue;
|
||||||
/* ECONNREFUSED is stale ICMP feedback on a connected
|
}
|
||||||
* UDP socket; EAGAIN means the send buffer is full.
|
switch (errno) {
|
||||||
* Both are transient - repaint and keep sending. */
|
case EINTR:
|
||||||
if (errno != ECONNREFUSED && errno != EAGAIN &&
|
continue; /* interrupted before sending - retry now */
|
||||||
errno != EWOULDBLOCK)
|
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");
|
perror("sendmmsg");
|
||||||
break;
|
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).
|
* to avoid IP fragmentation (e.g. 207 pixels ~= 1451 B fits a 1500 B link).
|
||||||
* Override at build time with -DPIXELS_PER_PACKET=N. */
|
* Override at build time with -DPIXELS_PER_PACKET=N. */
|
||||||
#ifndef PIXELS_PER_PACKET
|
#ifndef PIXELS_PER_PACKET
|
||||||
# define PIXELS_PER_PACKET 120
|
# define PIXELS_PER_PACKET 200
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue