=== modified file 'src/DiskIO/DiskThreads/CommIO.cc'
--- src/DiskIO/DiskThreads/CommIO.cc	2012-08-31 16:57:39 +0000
+++ src/DiskIO/DiskThreads/CommIO.cc	2012-10-18 08:32:01 +0000
@@ -41,13 +41,16 @@
 void
 CommIO::Initialise()
 {
+    if (CommIO::Initialised)
+        return;
+
     /* Initialize done pipe signal */
     int DonePipe[2];
     if (pipe(DonePipe)) {}
     DoneFD = DonePipe[1];
     DoneReadFD = DonePipe[0];
-    fd_open(DoneReadFD, FD_PIPE, "async-io completetion event: main");
-    fd_open(DoneFD, FD_PIPE, "async-io completetion event: threads");
+    fd_open(DoneReadFD, FD_PIPE, "async-io completion event: main");
+    fd_open(DoneFD, FD_PIPE, "async-io completion event: threads");
     commSetNonBlocking(DoneReadFD);
     commSetNonBlocking(DoneFD);
     Comm::SetSelect(DoneReadFD, COMM_SELECT_READ, NULLFDHandler, NULL, 0);

=== modified file 'src/DiskIO/DiskThreads/CommIO.h'
--- src/DiskIO/DiskThreads/CommIO.h	2012-08-28 13:00:30 +0000
+++ src/DiskIO/DiskThreads/CommIO.h	2012-10-18 08:32:56 +0000
@@ -22,12 +22,13 @@
     static int DoneReadFD;
 };
 
-/* Inline code. TODO: make structued approach to inlining */
+/* Inline code. TODO: make structured approach to inlining */
 void
 CommIO::NotifyIOCompleted()
 {
-    if (!Initialised)
-        Initialise();
+    if (!Initialised) {
+        fatalf("Disk Threads I/O pipes not initialized before first use.");
+    }
 
     if (!DoneSignalled) {
         DoneSignalled = true;

=== modified file 'src/DiskIO/DiskThreads/aiops.cc'
--- src/DiskIO/DiskThreads/aiops.cc	2012-10-03 17:32:57 +0000
+++ src/DiskIO/DiskThreads/aiops.cc	2012-10-18 08:59:11 +0000
@@ -306,6 +306,10 @@
 
     done_queue.blocked = 0;
 
+    // Initialize the thread I/O pipes before creating any threads
+    // see bug 3189 comment 5 about race conditions.
+    CommIO::Initialize();
+
     /* Create threads and get them to sit in their wait loop */
     squidaio_thread_pool = memPoolCreate("aio_thread", sizeof(squidaio_thread_t));
 


