master
leitner 21 years ago
parent 63ba06c763
commit 3c4f34b95e

@ -24,62 +24,67 @@ int64 iob_send(int64 s,io_batch* b) {
if (b->bytesleft==0) return 0; if (b->bytesleft==0) return 0;
last=array_start(&b->b)+array_bytes(&b->b); last=array_start(&b->b)+array_bytes(&b->b);
if (!(e=array_get(&b->b,sizeof(io_entry),b->next)))
return -1; /* can't happen error */
v=alloca(b->bufs*sizeof(struct iovec)); v=alloca(b->bufs*sizeof(struct iovec));
for (;;) {
if (!(e=array_get(&b->b,sizeof(io_entry),b->next)))
return -1; /* can't happen error */
#ifdef BSD_SENDFILE #ifdef BSD_SENDFILE
/* BSD sendfile can send headers and trailers. If we run on BSD, we /* BSD sendfile can send headers and trailers. If we run on BSD, we
* should try to exploit this. */ * should try to exploit this. */
headers=trailers=0; headers=trailers=0;
#endif #endif
for (i=0; e+i<last; ++i) { for (i=0; e+i<last; ++i) {
if (e[i].type==FROMFILE) break;
v[i].iov_base=e[i].buf+e[i].offset;
v[i].iov_len=e[i].n-e[i].offset;
}
headers=i;
#ifdef BSD_SENDFILE
if (e[i].type==FROMFILE) {
off_t sbytes;
struct sf_hdtr hdr;
int r;
for (++i; e+i<last; ++i) {
if (e[i].type==FROMFILE) break; if (e[i].type==FROMFILE) break;
v[i-1].iov_base=e[i].buf+e[i].offset; v[i].iov_base=e[i].buf+e[i].offset;
v[i-1].iov_len=e[i].n-e[i].offset; v[i].iov_len=e[i].n-e[i].offset;
++trailers;
} }
hdr.headers=v; hdr.hdr_cnt=headers; headers=i;
hdr.trailers=v+headers; hdr.trl_cnt=trailers; #ifdef BSD_SENDFILE
r=sendfile(e[headers].fd,s,e[headers].offset,e[headers].n,&hdr,&sbytes,0); if (e[i].type==FROMFILE) {
if (r==0) off_t sbytes;
sent=b->bytesleft; struct sf_hdtr hdr;
else if (r==-1 && errno==EAGAIN) int r;
sent=sbytes; for (++i; e+i<last; ++i) {
else if (e[i].type==FROMFILE) break;
sent=-1; v[i-1].iov_base=e[i].buf+e[i].offset;
} else v[i-1].iov_len=e[i].n-e[i].offset;
sent=writev(s,v,headers); ++trailers;
}
hdr.headers=v; hdr.hdr_cnt=headers;
hdr.trailers=v+headers; hdr.trl_cnt=trailers;
r=sendfile(e[headers].fd,s,e[headers].offset,e[headers].n,&hdr,&sbytes,0);
if (r==0)
sent=b->bytesleft;
else if (r==-1 && errno==EAGAIN)
sent=sbytes;
else
sent=-1;
} else
sent=writev(s,v,headers);
#else #else
if (headers) if (headers)
sent=writev(s,v,headers); sent=writev(s,v,headers);
else else
sent=io_sendfile(s,e->fd,e->offset,e->n); sent=io_sendfile(s,e->fd,e->offset,e->n);
#endif #endif
if (sent==b->bytesleft) if (sent==b->bytesleft) {
b->bytesleft=0; b->bytesleft=0;
else if (sent>0) { break;
int64 rest=sent; } else if (sent>0) {
b->bytesleft-=rest; int64 rest=sent;
for (i=0; e+i<last; ++i) { b->bytesleft-=rest;
if (e[i].n-e[i].offset<rest) { for (i=0; e+i<last; ++i) {
rest-=e[i].n-e[i].offset; if (e[i].n-e[i].offset<=rest) {
++b->next; rest-=e[i].n-e[i].offset;
} else { ++b->next;
e[i].offset+=rest; if (!rest) break;
break; } else {
e[i].offset+=rest;
goto abort;
}
} }
} } else break;
} }
abort:
return sent; return sent;
} }

Loading…
Cancel
Save