From e86a457f5c8d04905524d2617385c0c0e08c4291 Mon Sep 17 00:00:00 2001 From: leitner Date: Fri, 19 Sep 2003 15:26:00 +0000 Subject: [PATCH] harmonize semantics of io_sendfile and iob_send --- CHANGES | 3 +++ io/io_sendfile.c | 24 +++++++++++++++++++++--- io/iob_send.c | 18 +++++++++--------- test/httpd.c | 2 +- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index 65d2bc6..8a91078 100644 --- a/CHANGES +++ b/CHANGES @@ -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) diff --git a/io/io_sendfile.c b/io/io_sendfile.c index d23b5a7..b92629c 100644 --- a/io/io_sendfile.c +++ b/io/io_sendfile.c @@ -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,(bytes0) { - 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; diff --git a/io/iob_send.c b/io/iob_send.c index 0a7a476..41c9514 100644 --- a/io/iob_send.c +++ b/io/iob_send.c @@ -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 diff --git a/test/httpd.c b/test/httpd.c index 397b631..071ae53 100644 --- a/test/httpd.c +++ b/test/httpd.c @@ -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);