limit iovec size for sendmsg code path to 50
This commit is contained in:
parent
fc7e04660f
commit
86e596b870
@ -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…
x
Reference in New Issue
Block a user