Browse Source

limit iovec size for sendmsg code path to 50

master
Felix von Leitner 5 months ago
parent
commit
b148d97cad
  1. 41
      io/iob_send.c

41
io/iob_send.c

@ -128,8 +128,8 @@ int64 iob_send(int64 s,io_batch* b) {
struct iovec* v;
uint64 total;
int64 sent;
long i;
long headers;
size_t i;
size_t headers;
#ifdef MSG_MORE
int docork;
#endif
@ -255,7 +255,42 @@ eagain:
memset(&msg,0,sizeof(msg));
msg.msg_iov=v;
msg.msg_iovlen=headers;
sent=sendmsg(s,&msg,MSG_MORE|ZEROCOPY);
/* Difficulty: sendmsg has a built-in limit on the cmsgdata on
* Linux, net.core.optmem_max with a 20k default size. So we
* need to do a little song and dance here to not trigger it */
if (headers > 50) {
size_t skip=0, totalsent=0;
for (skip=0; skip<headers; skip+=50) {
size_t i,n;
int64 l=0;
n = headers-skip; if (n > 50) n=50;
for (i=0; i<n; ++i) l += v[skip+i].iov_len;
// printf("writing %d records from offset %d, %d bytes\n", skip, n, l);
msg.msg_iov=v + skip;
msg.msg_iovlen=n;
sent=sendmsg(s,&msg,MSG_MORE|ZEROCOPY);
if (sent > 0) totalsent += sent;
if (sent == l) continue; // we sent as much as we wanted, go for next batch
if (sent >= 0) { // we wrote something but not the whole batch
sent = totalsent;
break;
}
// we got an error, maybe EAGAIN
if (errno==EAGAIN) {
if (totalsent == 0) {
io_eagain_write(s);
return -1;
}
sent = totalsent;
// fall through
}
// actual error
break;
}
// if we get here, we wrote it all
sent = totalsent;
} else
sent=sendmsg(s,&msg,MSG_MORE|ZEROCOPY);
}
}
if (sent==-1) {

Loading…
Cancel
Save