Index: benchmark/io/http/main.cfa
===================================================================
--- benchmark/io/http/main.cfa	(revision 7ce88736e34bf185c4d55149f3117c28e91f9106)
+++ benchmark/io/http/main.cfa	(revision 3f95dab13f46929be6718df860c0fada67fb412c)
@@ -302,4 +302,12 @@
 					sout | "done";
 
+					//===================
+					// Close Files
+					if( options.file_cache.path ) {
+						sout | "Closing open files..." | nonl; flush( sout );
+						close_cache();
+						sout | "done";
+					}
+
 					sout | "Stopping accept threads..." | nonl; flush( sout );
 					for(i; nacceptors) {
@@ -346,4 +354,12 @@
 					}
 					sout | "done";
+
+					//===================
+					// Close Files
+					if( options.file_cache.path ) {
+						sout | "Closing open files..." | nonl; flush( sout );
+						close_cache();
+						sout | "done";
+					}
 
 					sout | "Stopping connection threads..." | nonl; flush( sout );
@@ -386,12 +402,4 @@
 	}
 	sout | "done";
-
-	//===================
-	// Close Files
-	if( options.file_cache.path ) {
-		sout | "Closing open files..." | nonl; flush( sout );
-		close_cache();
-		sout | "done";
-	}
 }
 
Index: benchmark/io/http/protocol.cfa
===================================================================
--- benchmark/io/http/protocol.cfa	(revision 7ce88736e34bf185c4d55149f3117c28e91f9106)
+++ benchmark/io/http/protocol.cfa	(revision 3f95dab13f46929be6718df860c0fada67fb412c)
@@ -29,5 +29,5 @@
 #define PLAINTEXT_MEMCPY
 #define PLAINTEXT_NOCOPY
-#define LINKED_IO
+// #define LINKED_IO
 
 static inline __s32 wait_res( io_future_t & this ) {
@@ -72,5 +72,4 @@
 		if( ret < 0 ) {
 			if( errno == ECONNRESET || errno == EPIPE ) { close(fd); return -ECONNRESET; }
-			if( errno == EAGAIN || errno == EWOULDBLOCK) return -EAGAIN;
 
 			abort( "'answer error' error: (%d) %s\n", (int)errno, strerror(errno) );
@@ -152,27 +151,42 @@
 }
 
-static int sendfile( int pipe[2], int fd, int ans_fd, size_t count ) {
+static int sendfile( int pipe[2], int fd, int ans_fd, size_t count, sendfile_stats_t & stats ) {
+	int zipf_idx = -1;
+	STATS: for(i; zipf_cnts) {
+		if(count <= zipf_sizes[i]) {
+			zipf_idx = i;
+			break STATS;
+		}
+	}
+	if(zipf_idx < 0) mutex(serr) serr | "SENDFILE" | count | " greated than biggest zipf file";
+
+
 	unsigned sflags = SPLICE_F_MOVE; // | SPLICE_F_MORE;
 	off_t offset = 0;
 	ssize_t ret;
 	SPLICE1: while(count > 0) {
-		ret = cfa_splice(ans_fd, &offset, pipe[1], 0p, count, sflags, CFA_IO_LAZY);
-		if( ret < 0 ) {
-			if( errno != EAGAIN && errno != EWOULDBLOCK) continue SPLICE1;
+		stats.tries++;
+		// ret = cfa_splice(ans_fd, &offset, pipe[1], 0p, count, sflags, CFA_IO_LAZY);
+		ret = splice(ans_fd, &offset, pipe[1], 0p, count, sflags);
+		if( ret <= 0 ) {
 			if( errno == ECONNRESET ) return -ECONNRESET;
 			if( errno == EPIPE ) return -EPIPE;
-			abort( "splice [0] error: (%d) %s\n", (int)errno, strerror(errno) );
-		}
-
+			abort( "splice [0] error: %d (%d) %s\n", ret, (int)errno, strerror(errno) );
+		}
 		count -= ret;
+		stats.splcin++;
+		if(count > 0) stats.avgrd[zipf_idx].calls++;
+		stats.avgrd[zipf_idx].bytes += ret;
+
 		size_t in_pipe = ret;
 		SPLICE2: while(in_pipe > 0) {
-			ret = cfa_splice(pipe[0], 0p, fd, 0p, in_pipe, sflags, CFA_IO_LAZY);
-			if( ret < 0 ) {
-				if( errno != EAGAIN && errno != EWOULDBLOCK) continue SPLICE2;
+			// ret = cfa_splice(pipe[0], 0p, fd, 0p, in_pipe, sflags, CFA_IO_LAZY);
+			ret = splice(pipe[0], 0p, fd, 0p, in_pipe, sflags);
+			if( ret <= 0 ) {
 				if( errno == ECONNRESET ) return -ECONNRESET;
 				if( errno == EPIPE ) return -EPIPE;
-				abort( "splice [1] error: (%d) %s\n", (int)errno, strerror(errno) );
+				abort( "splice [1] error: %d (%d) %s\n", ret, (int)errno, strerror(errno) );
 			}
+			stats.splcot++;
 			in_pipe -= ret;
 		}
@@ -506,8 +520,7 @@
 		return len + fsize;
 	#else
-		stats.tries++;
 		int ret = answer_header(fd, fsize);
 		if( ret < 0 ) { close(fd); return ret; }
-		return sendfile(pipe, fd, ans_fd, fsize);
+		return sendfile(pipe, fd, ans_fd, fsize, stats);
 	#endif
 }
@@ -528,7 +541,6 @@
 		}
 		// int ret = read(fd, (void*)it, count);
-		if(ret == 0 ) return [OK200, true, 0, 0];
+		if(ret == 0 ) { close(fd); return [OK200, true, 0, 0]; }
 		if(ret < 0 ) {
-			if( errno == EAGAIN || errno == EWOULDBLOCK) continue READ;
 			if( errno == ECONNRESET ) { close(fd); return [E408, true, 0, 0]; }
 			if( errno == EPIPE ) { close(fd); return [E408, true, 0, 0]; }
Index: benchmark/io/http/worker.cfa
===================================================================
--- benchmark/io/http/worker.cfa	(revision 7ce88736e34bf185c4d55149f3117c28e91f9106)
+++ benchmark/io/http/worker.cfa	(revision 3f95dab13f46929be6718df860c0fada67fb412c)
@@ -13,4 +13,6 @@
 #include "protocol.hfa"
 #include "filecache.hfa"
+
+static const unsigned long long period = 50_000_000;
 
 //=============================================================================================
@@ -95,5 +97,10 @@
 		// Send the desired file
 		int ret = answer_sendfile( this.pipe, fd, ans_fd, count, this.stats.sendfile );
-		if( ret == -ECONNRESET ) break REQUEST;
+		if(ret < 0) {
+			if( ret == -ECONNABORTED ) break REQUEST;
+			if( ret == -ECONNRESET ) break REQUEST;
+			if( ret == -EPIPE ) break REQUEST;
+			abort( "sendfile error: %d (%d) %s\n", ret, (int)errno, strerror(errno) );
+		}
 
 		if( options.log ) mutex(sout) sout | "=== Answer sent ===";
@@ -102,5 +109,5 @@
 	if (stats_thrd) {
 		unsigned long long next = rdtscl();
-		if(next > (last + 500000000)) {
+		if(next > (last + period)) {
 			if(try_lock(stats_thrd->stats.lock __cfaabi_dbg_ctx2)) {
 				push(this.stats.sendfile, stats_thrd->stats.send);
@@ -141,4 +148,6 @@
 		char buffer[len];
 		handle_connection( this.conn, fd, buffer, len, 0p, last );
+		this.conn.stats.sendfile.maxfd = max(this.conn.stats.sendfile.maxfd, fd);
+		this.conn.stats.sendfile.close++;
 
 		if( options.log ) mutex(sout) sout | "=== Connection closed ===";
@@ -162,4 +171,5 @@
 	/* paranoid */ assert( this.conn.pipe[0] != -1 );
 	/* paranoid */ assert( this.conn.pipe[1] != -1 );
+	this.conn.stats.sendfile.maxfd = max(this.conn.pipe[0], this.conn.pipe[1]);
 	for() {
 		size_t len = options.socket.buflen;
@@ -173,8 +183,14 @@
 		if( options.log ) mutex(sout) sout | "=== Waiting new connection ===";
 		handle_connection( this.conn, p.out.fd, buffer, len, &p.f, last );
+		if(this.done) break;
+		this.conn.stats.sendfile.maxfd = max(this.conn.stats.sendfile.maxfd, p.out.fd);
+		this.conn.stats.sendfile.close++;
 
 		if( options.log ) mutex(sout) sout | "=== Connection closed ===";
-		if(this.done) break;
-	}
+	}
+
+	lock(stats_thrd->stats.lock __cfaabi_dbg_ctx2);
+	push(this.conn.stats.sendfile, stats_thrd->stats.send);
+	unlock(stats_thrd->stats.lock);
 }
 
@@ -198,4 +214,5 @@
 
 static inline void push_connection( Acceptor & this, int fd ) {
+	this.stats.accepts++;
 	PendingRead * p = 0p;
 	for() {
@@ -212,5 +229,6 @@
 
 // #define ACCEPT_SPIN
-#define ACCEPT_MANY
+#define ACCEPT_ONE
+// #define ACCEPT_MANY
 
 void main( Acceptor & this ) {
@@ -232,5 +250,4 @@
 			abort( "accept error: (%d) %s\n", (int)errno, strerror(errno) );
 		}
-		this.stats.accepts++;
 
 		if(this.done) return;
@@ -242,5 +259,35 @@
 		if (stats_thrd) {
 			unsigned long long next = rdtscl();
-			if(next > (last + 500000000)) {
+			if(next > (last + period)) {
+				if(try_lock(stats_thrd->stats.lock)) {
+					push(this.stats, stats_thrd->stats.accpt);
+					unlock(stats_thrd->stats.lock);
+					last = next;
+				}
+			}
+		}
+
+		if( options.log ) sout | "=== Accepting connection ===";
+	}
+
+#elif defined(ACCEPT_ONE)
+	if( options.log ) sout | "=== Accepting connection ===";
+	for() {
+		int fd = cfa_accept4(this.sockfd, this.[addr, addrlen, flags], 0);
+		if(fd < 0) {
+			if( errno == ECONNABORTED ) break;
+			if( this.done && (errno == EINVAL || errno == EBADF) ) break;
+			abort( "accept error: (%d) %s\n", (int)errno, strerror(errno) );
+		}
+
+		if(this.done) return;
+
+		if( options.log ) sout | "=== New connection" | fd | "" | ", waiting for requests ===";
+
+		if(fd) push_connection(this, fd);
+
+		if (stats_thrd) {
+			unsigned long long next = rdtscl();
+			if(next > (last + period)) {
 				if(try_lock(stats_thrd->stats.lock)) {
 					push(this.stats, stats_thrd->stats.accpt);
@@ -269,5 +316,5 @@
 		if (stats_thrd) {
 			unsigned long long next = rdtscl();
-			if(next > (last + 500000000)) {
+			if(next > (last + period)) {
 				if(try_lock(stats_thrd->stats.lock __cfaabi_dbg_ctx2)) {
 					push(this.stats, stats_thrd->stats.accpt);
@@ -284,5 +331,4 @@
 				int fd = get_res(res);
 				reset(res);
-				this.stats.accepts++;
 				if(fd < 0) {
 					if( errno == ECONNABORTED ) continue;
@@ -319,3 +365,6 @@
 #error no accept algorithm specified
 #endif
-}
+	lock(stats_thrd->stats.lock);
+	push(this.stats, stats_thrd->stats.accpt);
+	unlock(stats_thrd->stats.lock);
+}
