|
|
|
@ -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,6 +255,41 @@ eagain:
|
|
|
|
|
memset(&msg,0,sizeof(msg));
|
|
|
|
|
msg.msg_iov=v;
|
|
|
|
|
msg.msg_iovlen=headers;
|
|
|
|
|
/* 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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|