From a0cde0fee94840c2507172154811cb02e2ab8d23 Mon Sep 17 00:00:00 2001 From: leitner Date: Thu, 19 Nov 2015 13:06:15 +0000 Subject: [PATCH] slight optimization for buffer_flush --- buffer/buffer_putflush.c | 45 ++++++++++++++++++++++++++++++++++++++++ buffer/buffer_stubborn.c | 5 +++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/buffer/buffer_putflush.c b/buffer/buffer_putflush.c index f33e4dc..84dcdaa 100644 --- a/buffer/buffer_putflush.c +++ b/buffer/buffer_putflush.c @@ -1,6 +1,51 @@ +#ifndef __MINGW32__ +#include +#include +#include +#endif #include "buffer.h" +#ifndef __unlikely +#ifdef __GNUC__ +#define __unlikely(x) __builtin_expect((x),0) +#else +#define __unlikely(x) (x) +#endif +#endif + +extern ssize_t buffer_stubborn(ssize_t (*op)(),int fd,const char* buf, size_t len,void* cookie); + int buffer_putflush(buffer* b,const char* x,size_t len) { + /* Since we know we are going to flush anyway, let's see if we can + * optimize a bit */ + if (!b->p) /* if the buffer is empty, just call buffer_stubborn directly */ + return buffer_stubborn(b->op,b->fd,x,len,b); +#ifndef __MINGW32__ + if (b->op==write) { + struct iovec v[2]; + ssize_t w; + size_t cl=b->p+len; + v[0].iov_base=b->x; + v[0].iov_len=b->p; + v[1].iov_base=(char*)x; + v[1].iov_len=len; + while ((w=writev(b->fd,v,2))<0) { + if (errno == EINTR) continue; + return -1; + } + if (__unlikely((size_t)w!=cl)) { + /* partial write. ugh. */ + if ((size_t)wop,b->fd,v[0].iov_base+w,v[0].iov_len-w,b) || + buffer_stubborn(b->op,b->fd,v[1].iov_base,v[0].iov_len,b)) return -1; + } else { + w-=v[0].iov_len; + return buffer_stubborn(b->op,b->fd,v[1].iov_base+w,v[1].iov_len-w,b); + } + } + return 0; + } +#endif if (buffer_put(b,x,len)<0) return -1; if (buffer_flush(b)<0) return -1; return 0; diff --git a/buffer/buffer_stubborn.c b/buffer/buffer_stubborn.c index 3ac07c0..2e00418 100644 --- a/buffer/buffer_stubborn.c +++ b/buffer/buffer_stubborn.c @@ -3,11 +3,12 @@ int buffer_stubborn(ssize_t (*op)(),int fd,const char* buf, size_t len,void* cookie) { ssize_t w; + errno=0; while (len) { - if ((w=op(fd,buf,len,cookie))<0) { + if ((w=op(fd,buf,len,cookie))<=0) { if (errno == EINTR) continue; return -1; - }; + } buf+=w; len-=(size_t)w; }