timeout
Nikola Vladov <[email protected]> 8 Apr 2006 19:11:10 -0000
| Newsgroups | gmane.comp.web.fnord |
|---|---|
| Message-ID | <[email protected]> |
I I modified fnord to use timeout. next part must be before
int main(...) The first line after main(...) in my code is
buffer_1->op = timeoutfrite;
Enjoy, Nikola
int timeoutwrite(int fd,char *buf,int len) {
time_t now, deadline;
struct pollfd x;
now = time(0);
deadline = now + WRITETIMEOUT;
x.fd = fd;
x.events = POLLOUT;
for (;;) {
if (deadline<=now) {
errno = ETIMEDOUT;
return -1;
}
x.revents=0;
if (poll(&x,1,(deadline-now)*1000)==1 &&
(x.revents & POLLOUT)) return write(fd,buf,len);
time(&now);
}
}
extern int buffer_stubborn(int (*op)(),int fd,const char* buf, unsigned int len);
static int serve_read_write(int fd) {
off_t todo = rangeend-rangestart;
off_t buf_len = buffer_1->a;
if (rangestart) lseek(fd,rangestart,SEEK_SET);
while (todo>0) {
int len = read(fd, buffer_1->x, todo > buf_len ? buf_len : todo);
if (len==-1) return 1;
todo -= len;
if (buffer_stubborn(timeoutwrite, 1, buffer_1->x, len))
return -1;
}
return 0;
}
#ifdef USE_MMAP
static int serve_mmap(int fd) {
off_t mapstart,maplen;
unsigned long mapofs;
char* map;
mapstart=rangestart&(~(off_t)0xfff); /* round down to 4k page */
maplen=rangeend-mapstart;
mapofs=rangestart-mapstart;
if (maplen>64*1024*1024) maplen=64*1024*1024;
map=mmap(0,maplen,PROT_READ,MAP_PRIVATE,fd,mapstart);
if (map==MAP_FAILED) {
if (errno==EINVAL && mapstart) {
/* try rounded to 64k pages */
mapstart=rangestart&0xffff;
maplen=rangeend-mapstart;
mapofs=rangestart-mapstart;
map=mmap(0,maplen,PROT_READ,MAP_PRIVATE,fd,mapstart);
if (map==MAP_FAILED)
/* didn't work, use read/write instead. */
return serve_read_write(fd);
} else return serve_read_write(fd);
}
while (rangestart<rangeend) {
if (buffer_stubborn(timeoutwrite,1,map+mapofs,(int)(maplen-mapofs)))
return -1;
rangestart+=maplen-mapofs;
mapstart+=maplen;
munmap(map,maplen); mapofs=0;
maplen=rangeend-mapstart;
if (maplen) {
if (maplen>64*1024*1024) maplen=64*1024*1024;
map=mmap(0,maplen,PROT_READ,MAP_SHARED,fd,mapstart);
if (map==MAP_FAILED)
/* can't happen, really */
return serve_read_write(fd);
}
}
return 0;
}
#endif
#ifdef USE_MMAP
#define SERVE_FILE serve_mmap
#else
#define SERVE_FILE serve_read_write
#endif
/* write from offset "rangestart" to offset "rangeend" to fd #1 */
static int serve_static_data(int fd) {
#ifdef TCP_CORK
{
int one=1;
setsockopt(1,IPPROTO_TCP,TCP_CORK,&one,sizeof(one));
corked=1;
}
#endif
if (buffer_flush(buffer_1)) return -1;
#ifdef USE_SENDFILE
/* for small files, sendfile is actually slower */
if (rangeend-rangestart < 4096) return serve_read_write(fd);
{
off_t offset=rangestart, l=rangeend-rangestart, c, w;
while (l) {
c=(l>(1ul<<31))?1ul<<31:l;
if ((w=sendfile(1,fd,&offset,c))==-1) {
rangestart = offset;
return SERVE_FILE(fd);
}
l-=w;
}
return 0;
}
#else
return SERVE_FILE(fd);
#endif
}