Index: benchmark/io/http/filecache.cfa
===================================================================
--- benchmark/io/http/filecache.cfa	(revision 3f1d9b57b3da9b311352c5822c26200c04fe2dd7)
+++ benchmark/io/http/filecache.cfa	(revision f00b26d473acc916ee96e28fa1365688d9b3c2da)
@@ -192,4 +192,13 @@
 }
 
+[int *, int] filefds(int extra) {
+	if(!file_cache.entries) {
+		abort("File cache not filled!\n");
+	}
+
+	return [aalloc(extra), 0];
+}
+
+
 void close_cache() {
 	for(idx; file_cache.size) {
Index: benchmark/io/http/filecache.hfa
===================================================================
--- benchmark/io/http/filecache.hfa	(revision 3f1d9b57b3da9b311352c5822c26200c04fe2dd7)
+++ benchmark/io/http/filecache.hfa	(revision f00b26d473acc916ee96e28fa1365688d9b3c2da)
@@ -11,3 +11,4 @@
 [int fd, size_t size] get_file( * const char file, size_t len );
 void fill_cache( const char * path );
+[int *, int] filefds( int extra );
 void close_cache();
Index: benchmark/io/http/main.cfa
===================================================================
--- benchmark/io/http/main.cfa	(revision 3f1d9b57b3da9b311352c5822c26200c04fe2dd7)
+++ benchmark/io/http/main.cfa	(revision f00b26d473acc916ee96e28fa1365688d9b3c2da)
@@ -93,8 +93,28 @@
 		&wait_connect = &chan;
 
+		int pipe_cnt = options.clopts.nworkers * 2;
+		int pipe_off;
+		int * fds;
+		[fds, pipe_off] = filefds( pipe_cnt );
+		for(i; 0 ~ pipe_cnt ~ 2) {
+			int ret = pipe(&fds[pipe_off + i]);
+			if( ret < 0 ) { abort( "pipe error: (%d) %s\n", (int)errno, strerror(errno) ); }
+		}
+
 		{
 			ServerProc procs[options.clopts.nprocs];
 			{
 				Worker workers[options.clopts.nworkers];
+				for(i; options.clopts.nworkers) {
+					if( options.file_cache.fixed_fds ) {
+						workers[i].pipe[0] = pipe_off + (i * 2) + 0;
+						workers[i].pipe[1] = pipe_off + (i * 2) + 1;
+					}
+					else {
+						workers[i].pipe[0] = fds[pipe_off + (i * 2) + 0];
+						workers[i].pipe[1] = fds[pipe_off + (i * 2) + 1];
+					}
+					unpark( workers[i] __cfaabi_dbg_ctx2 );
+				}
 				printf("%d workers started on %d processors\n", options.clopts.nworkers, options.clopts.nprocs);
 				{
@@ -117,4 +137,12 @@
 			printf("Workers Closed\n");
 		}
+
+		for(i; pipe_cnt) {
+			ret = close( fds[pipe_off + i] );
+			if(ret < 0) {
+				abort( "close pipe error: (%d) %s\n", (int)errno, strerror(errno) );
+			}
+		}
+		free(fds);
 	}
 
Index: benchmark/io/http/worker.cfa
===================================================================
--- benchmark/io/http/worker.cfa	(revision 3f1d9b57b3da9b311352c5822c26200c04fe2dd7)
+++ benchmark/io/http/worker.cfa	(revision f00b26d473acc916ee96e28fa1365688d9b3c2da)
@@ -12,14 +12,4 @@
 #include "filecache.hfa"
 
-extern "C" {
-// extern ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
-extern ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);
-}
-
-ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) {
-	return splice(in_fd, offset, out_fd, 0p, count, 0);
-}
-
-
 //=============================================================================================
 // Worker Thread
@@ -27,9 +17,13 @@
 void ?{}( Worker & this ) {
 	((thread&)this){ "Server Worker Thread", *options.clopts.instance };
-	int ret = pipe(this.pipe);
-	if( ret < 0 ) { abort( "pipe error: (%d) %s\n", (int)errno, strerror(errno) ); }
+	this.pipe[0] = -1;
+	this.pipe[1] = -1;
 }
 
 void main( Worker & this ) {
+	park( __cfaabi_dbg_ctx );
+	/* paranoid */ assert( this.pipe[0] != -1 );
+	/* paranoid */ assert( this.pipe[1] != -1 );
+
 	CONNECTION:
 	for() {
