add loop
This commit is contained in:
parent
63ba06c763
commit
3c4f34b95e
107
io/iob_send.c
107
io/iob_send.c
@ -24,62 +24,67 @@ int64 iob_send(int64 s,io_batch* b) {
|
||||
|
||||
if (b->bytesleft==0) return 0;
|
||||
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));
|
||||
for (;;) {
|
||||
if (!(e=array_get(&b->b,sizeof(io_entry),b->next)))
|
||||
return -1; /* can't happen error */
|
||||
#ifdef BSD_SENDFILE
|
||||
/* BSD sendfile can send headers and trailers. If we run on BSD, we
|
||||
* should try to exploit this. */
|
||||
headers=trailers=0;
|
||||
/* BSD sendfile can send headers and trailers. If we run on BSD, we
|
||||
* should try to exploit this. */
|
||||
headers=trailers=0;
|
||||
#endif
|
||||
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;
|
||||
v[i-1].iov_base=e[i].buf+e[i].offset;
|
||||
v[i-1].iov_len=e[i].n-e[i].offset;
|
||||
++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
|
||||
if (headers)
|
||||
sent=writev(s,v,headers);
|
||||
else
|
||||
sent=io_sendfile(s,e->fd,e->offset,e->n);
|
||||
#endif
|
||||
if (sent==b->bytesleft)
|
||||
b->bytesleft=0;
|
||||
else if (sent>0) {
|
||||
int64 rest=sent;
|
||||
b->bytesleft-=rest;
|
||||
for (i=0; e+i<last; ++i) {
|
||||
if (e[i].n-e[i].offset<rest) {
|
||||
rest-=e[i].n-e[i].offset;
|
||||
++b->next;
|
||||
} else {
|
||||
e[i].offset+=rest;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
v[i-1].iov_base=e[i].buf+e[i].offset;
|
||||
v[i-1].iov_len=e[i].n-e[i].offset;
|
||||
++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
|
||||
if (headers)
|
||||
sent=writev(s,v,headers);
|
||||
else
|
||||
sent=io_sendfile(s,e->fd,e->offset,e->n);
|
||||
#endif
|
||||
if (sent==b->bytesleft) {
|
||||
b->bytesleft=0;
|
||||
break;
|
||||
} else if (sent>0) {
|
||||
int64 rest=sent;
|
||||
b->bytesleft-=rest;
|
||||
for (i=0; e+i<last; ++i) {
|
||||
if (e[i].n-e[i].offset<=rest) {
|
||||
rest-=e[i].n-e[i].offset;
|
||||
++b->next;
|
||||
if (!rest) break;
|
||||
} else {
|
||||
e[i].offset+=rest;
|
||||
goto abort;
|
||||
}
|
||||
}
|
||||
} else break;
|
||||
}
|
||||
abort:
|
||||
return sent;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user