harmonize semantics of io_sendfile and iob_send

master
leitner 22 years ago
parent 85bfbeb420
commit e86a457f5c

@ -2,6 +2,9 @@
add Linux SIGIO support to IO
expand IO api to be able to cope with edge triggered event
notification: introduce io_eagain
the integer scan routines should only write *dest if they actually
scanned something
io_sendfile and iob_send should return -1 to -3 just like io_trywrite
0.16:
add buffer_fromsa (make buffer from stralloc)

@ -11,7 +11,7 @@ int64 io_sendfile(int64 s,int64 fd,uint64 off,uint64 n) {
int r=sendfile(fd,s,off,n,0,&sbytes,0);
if (r==0) return n;
if (r==-1)
return (errno==EAGAIN?sbytes:-1);
return (errno==EAGAIN?(sbytes?sbytes:-1):-3);
}
#elif defined(__linux__)
@ -26,7 +26,16 @@ _syscall4(int,sendfile,int,out,int,in,long *,offset,unsigned long,count)
int64 io_sendfile(int64 s,int64 fd,uint64 off,uint64 n) {
off_t o=off;
return sendfile(s,fd,&o,n);
io_entry* e=array_get(&io_fds,sizeof(io_entry),s);
off_t i=sendfile(s,fd,&o,n);
if (i==-1) {
if (e) {
e->canwrite=0;
e->next_write=-1;
}
if (errno!=EAGAIN) i=-3;
}
return i;
}
#else
@ -37,6 +46,7 @@ int64 io_sendfile(int64 out,int64 in,uint64 off,uint64 bytes) {
char buf[BUFSIZE];
int n,m;
uint64 sent=0;
io_entry* e=array_get(&io_fds,sizeof(io_entry),out);
if (lseek(in,off,SEEK_SET) != off)
return -1;
while (bytes>0) {
@ -44,8 +54,16 @@ int64 io_sendfile(int64 out,int64 in,uint64 off,uint64 bytes) {
if ((n=read(in,tmp,(bytes<BUFSIZE)?bytes:BUFSIZE))<=0)
return (sent?sent:-1);
while (n>0) {
if ((m=write(out,tmp,n))<0)
if ((m=write(out,tmp,n))<0) {
if (m==-1) {
if (e) {
e->canwrite=0;
e->next_write=-1;
}
return errno==EAGAIN?(sent?sent:-1):-3;
}
goto abort;
}
sent+=m;
n-=m;
tmp+=m;

@ -59,11 +59,13 @@ int64 iob_send(int64 s,io_batch* b) {
if (r==0)
sent=b->bytesleft;
else if (r==-1 && errno==EAGAIN)
sent=sbytes;
if ((sent=sbytes)) sent=-1;
else
sent=-1;
} else
sent=-3;
} else {
sent=writev(s,v,headers);
if (sent==-1 && errno!=EAGAIN) sent=-3;
}
#else
#ifdef TCP_CORK
if (b->bufs && b->files && !b->next) {
@ -71,18 +73,16 @@ int64 iob_send(int64 s,io_batch* b) {
setsockopt(s,IPPROTO_TCP,TCP_CORK,&one,sizeof(one));
}
#endif
if (headers)
if (headers) {
sent=writev(s,v,headers);
else
if (sent==-1 && errno==EAGAIN) sent=-3;
} else
sent=io_sendfile(s,e->fd,e->offset,e->n);
#endif
if (sent>0)
total+=sent;
else
if (!total) {
if (errno!=EAGAIN) return -3;
return -1;
}
return total?total:sent;
if (sent==b->bytesleft) {
b->bytesleft=0;
#ifdef TCP_CORK

@ -275,7 +275,7 @@ emerge:
struct http_data* h=io_getcookie(i);
int64 r=iob_send(i,&h->iob);
/* printf("iob_send returned %lld\n",r); */
if (r==-1) io_eagain(i);
if (r==-1) io_eagain(i); else
if (r<=0) {
array_trunc(&h->r);
iob_reset(&h->iob);

Loading…
Cancel
Save