---------------------
PatchSet 1134 
Date: 2004/12/26 09:23:30
Author: serassio
Branch: nt
Tag: (none) 
Log:
Added WinAIO DISKIO module

Members: 
	port/win32/include/aio.h:1.2.18.2->1.2.18.3(DEAD) 
	port/win32/src/aio.cc:1.1.6.3->1.1.6.4(DEAD) 
	src/Makefile.am:1.26.2.35->1.26.2.36 
	src/DiskIO/WinAIO/WinAIODiskFile.cc:1.1->1.1.2.1 
	src/DiskIO/WinAIO/WinAIODiskFile.h:1.1->1.1.2.1 
	src/DiskIO/WinAIO/WinAIODiskIOModule.cc:1.1->1.1.2.1 
	src/DiskIO/WinAIO/WinAIODiskIOModule.h:1.1->1.1.2.1 
	src/DiskIO/WinAIO/WinAIODiskIOStrategy.cc:1.1->1.1.2.1 
	src/DiskIO/WinAIO/WinAIODiskIOStrategy.h:1.1->1.1.2.1 
	src/DiskIO/WinAIO/Winaio.cc:1.1->1.1.2.1 
	src/DiskIO/WinAIO/Winaio.h:1.1->1.1.2.1 
	src/DiskIO/WinAIO/async_io.h:1.1->1.1.2.1 

--- squid3/port/win32/include/aio.h	Wed Feb 14 13:34:01 2007
+++ /dev/null	Wed Feb 14 13:33:00 2007
@@ -1,58 +0,0 @@
-#ifndef __WIN32_AIO_H__
-#define __WIN32_AIO_H__
-
-#ifdef _SQUID_CYGWIN_
-#include <windows.h>
-#endif
-
-#ifndef off64_t
-typedef int64_t	off64_t;
-#endif
-
-union sigval {
-    int sival_int; /* integer value */
-    void *sival_ptr; /* pointer value */
-};
-
-struct sigevent {
-    int sigev_notify; /* notification mode */
-    int sigev_signo; /* signal number */
-    union sigval sigev_value; /* signal value */
-};
-
-struct aiocb64 {
-    int aio_fildes; /* file descriptor */
-    void *aio_buf; /* buffer location */
-    size_t aio_nbytes; /* length of transfer */
-    off64_t aio_offset; /* file offset */
-    int aio_reqprio; /* request priority offset */
-    struct sigevent aio_sigevent; /* signal number and offset */
-    int aio_lio_opcode; /* listio operation */
-};
-
-struct aiocb {
-    int aio_fildes; /* file descriptor */
-    void *aio_buf; /* buffer location */
-    size_t aio_nbytes; /* length of transfer */
-#if (_FILE_OFFSET_BITS == 64)
-    off64_t aio_offset; /* file offset */
-#else
-    off_t aio_offset; /* file offset */
-#endif
-    int aio_reqprio; /* request priority offset */
-    struct sigevent aio_sigevent; /* signal number and offset */
-    int aio_lio_opcode; /* listio operation */
-};
-
-int aio_read(struct aiocb *);
-int aio_write(struct aiocb *);
-ssize_t aio_return(struct aiocb *);
-int aio_error(const struct aiocb *);
-int aio_read64(struct aiocb64 *);
-int aio_write64(struct aiocb64 *);
-ssize_t aio_return64(struct aiocb64 *);
-int aio_error64(const struct aiocb64 *);
-int aio_open(const char *, int);
-void aio_close(int);
-
-#endif
--- squid3/port/win32/src/aio.cc	Wed Feb 14 13:34:01 2007
+++ /dev/null	Wed Feb 14 13:33:00 2007
@@ -1,308 +0,0 @@
-
-/*
- * $Id: aio.cc,v 1.1.6.3 2004/11/01 10:22:10 serassio Exp $
- *
- * DEBUG: section 81    aio_xxx() POSIX emulation on WIN32 for COSS
- * AUTHOR: Guido Serassio
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; see the CREDITS file for full details.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *  
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *  
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
- *
- */
-
-#include "squid.h"
-#include <aio.h>
-
-#ifdef _SQUID_WIN32_
-VOID CALLBACK IoCompletionRoutine(DWORD dwErrorCode, 
-        DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped) 
-{ 
-    struct aiocb *aiocbp = (struct aiocb *) lpOverlapped->hEvent;
-
-    aiocbp->aio_sigevent.sigev_notify = dwErrorCode;
-    aiocbp->aio_sigevent.sigev_signo = dwNumberOfBytesTransfered;
-    debug(81,7) ("AIO operation complete: errorcode=%ld nbytes=%ld\n", dwErrorCode, dwNumberOfBytesTransfered);
-    xfree(lpOverlapped); 
-} 
-
-
-int aio_read(struct aiocb *aiocbp)
-{
-    LPOVERLAPPED Overlapped;
-    BOOL IoOperationStatus; 
-
-    /* Allocate an overlapped structure. */
-    Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED)); 
-    if (!Overlapped) { 
-	errno = ENOMEM; 
-        return -1; 
-    } 
-
-#if _FILE_OFFSET_BITS==64
-#ifdef __GNUC__
-    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
-    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
-#else
-    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
-    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
-#endif 
-#else
-    Overlapped->Offset = aiocbp->aio_offset; 
-    Overlapped->OffsetHigh = 0;
-#endif
-    Overlapped->hEvent = aiocbp;
-    aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
-    aiocbp->aio_sigevent.sigev_signo = -1;
-
-    IoOperationStatus = ReadFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
-				    aiocbp->aio_buf, 
-				    aiocbp->aio_nbytes, 
-				    Overlapped,
-				    IoCompletionRoutine); 
-
-    /* Test to see if the I/O was queued successfully. */
-    if (!IoOperationStatus) {
-	errno = GetLastError(); 
-	debug(81,1) ("aio_read: GetLastError=%i\n", errno);
-        return -1; 
-    }
-
-    /* The I/O queued successfully. Go back into the 
-       alertable wait for I/O completion or for 
-       more I/O requests. */
-    return 0;
-}
-
-
-int aio_read64(struct aiocb64 *aiocbp)
-{
-    LPOVERLAPPED Overlapped;
-    BOOL IoOperationStatus; 
-
-    /* Allocate an overlapped structure. */
-    Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED)); 
-    if (!Overlapped) { 
-	errno = ENOMEM; 
-        return -1; 
-    } 
-
-#ifdef __GNUC__
-    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
-    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
-#else
-    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
-    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
-#endif
-    Overlapped->hEvent = aiocbp;
-    aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
-    aiocbp->aio_sigevent.sigev_signo = -1;
-
-    IoOperationStatus = ReadFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
-				    aiocbp->aio_buf, 
-				    aiocbp->aio_nbytes, 
-				    Overlapped,
-				    IoCompletionRoutine); 
-
-    /* Test to see if the I/O was queued successfully. */
-    if (!IoOperationStatus) {
-	errno = GetLastError(); 
-	debug(81,1) ("aio_read: GetLastError=%i\n", errno);
-        return -1; 
-    }
-
-    /* The I/O queued successfully. Go back into the 
-       alertable wait for I/O completion or for 
-       more I/O requests. */
-    return 0;
-}
-
-
-int aio_write(struct aiocb *aiocbp)
-
-{
-    LPOVERLAPPED Overlapped;
-    BOOL IoOperationStatus; 
-
-    /* Allocate an overlapped structure. */
-    Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED)); 
-    if (!Overlapped) { 
-	errno = ENOMEM; 
-        return -1; 
-    } 
-#if _FILE_OFFSET_BITS==64
-#ifdef __GNUC__
-    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
-    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
-#else
-    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
-    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
-#endif
-#else
-    Overlapped->Offset = aiocbp->aio_offset; 
-    Overlapped->OffsetHigh = 0;
-#endif
-    Overlapped->hEvent = aiocbp;
-    aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
-    aiocbp->aio_sigevent.sigev_signo = -1;
-
-    IoOperationStatus = WriteFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
-				    aiocbp->aio_buf, 
-				    aiocbp->aio_nbytes, 
-				    Overlapped,
-				    IoCompletionRoutine); 
- 
-    /* Test to see if the I/O was queued successfully. */
-    if (!IoOperationStatus) {
-	errno = GetLastError(); 
-	debug(81,1) ("aio_write: GetLastError=%i\n", errno);
-        return -1; 
-    }
-
-    /* The I/O queued successfully. Go back into the 
-       alertable wait for I/O completion or for 
-       more I/O requests. */
-    return 0;
-}
-
-
-int aio_write64(struct aiocb64 *aiocbp)
-
-{
-    LPOVERLAPPED Overlapped;
-    BOOL IoOperationStatus; 
-
-    /* Allocate an overlapped structure. */
-    Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED)); 
-    if (!Overlapped) { 
-	errno = ENOMEM; 
-        return -1; 
-    } 
-#ifdef __GNUC__
-    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
-    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
-#else
-    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
-    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
-#endif
-    Overlapped->hEvent = aiocbp;
-    aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
-    aiocbp->aio_sigevent.sigev_signo = -1;
-
-    IoOperationStatus = WriteFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
-				    aiocbp->aio_buf, 
-				    aiocbp->aio_nbytes, 
-				    Overlapped,
-				    IoCompletionRoutine); 
- 
-    /* Test to see if the I/O was queued successfully. */
-    if (!IoOperationStatus) {
-	errno = GetLastError(); 
-	debug(81,1) ("aio_write: GetLastError=%i\n", errno);
-        return -1; 
-    }
-
-    /* The I/O queued successfully. Go back into the 
-       alertable wait for I/O completion or for 
-       more I/O requests. */
-    return 0;
-}
-
-
-ssize_t aio_return(struct aiocb * aiocbp)
-
-{
-    return aiocbp->aio_sigevent.sigev_signo;
-}
-
-
-ssize_t aio_return64(struct aiocb64 * aiocbp)
-
-{
-    return aiocbp->aio_sigevent.sigev_signo;
-}
-
-
-int aio_error(const struct aiocb * aiocbp)
-
-{
-    return aiocbp->aio_sigevent.sigev_notify;
-}
-
-
-int aio_error64(const struct aiocb64 * aiocbp)
-
-{
-    return aiocbp->aio_sigevent.sigev_notify;
-}
-
-
-int aio_open(const char *path, int mode)
-{
-    HANDLE hndl;
-    DWORD dwCreationDisposition;
-    DWORD dwDesiredAccess;
-    int fd;
-
-    if (mode & O_WRONLY)
-	mode |= O_APPEND;
-    mode |= O_BINARY;
-    errno = 0;
-    if (mode & O_WRONLY)
-        dwDesiredAccess = GENERIC_WRITE;
-    else
-	dwDesiredAccess = (mode & O_RDONLY) ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE;
-    if (mode & O_TRUNC)
-        dwCreationDisposition = CREATE_ALWAYS;
-    else
-	dwCreationDisposition = (mode & O_CREAT) ? OPEN_ALWAYS : OPEN_EXISTING;
-
-    if ((hndl = CreateFile(path,	/* file name               */
-		dwDesiredAccess,	/* access mode             */
-		0,			/* share mode              */
-		NULL,			/* SD                      */
-		dwCreationDisposition,	/* how to create           */
-		FILE_FLAG_OVERLAPPED,	/* file attributes         */
-		NULL			/* handle to template file */
-		)) != INVALID_HANDLE_VALUE) {
-	statCounter.syscalls.disk.opens++;
-	fd = _open_osfhandle((long) hndl, 0);
-	commSetCloseOnExec(fd);
-	fd_open(fd, FD_FILE, path);
-    } else {
-	errno = GetLastError();
-	fd = DISK_ERROR;
-    }
-    return fd;
-}
-
-
-void aio_close(int fd)
-{
-    CloseHandle((HANDLE)_get_osfhandle(fd));
-    fd_close(fd);
-    statCounter.syscalls.disk.closes++;
-}
-#endif
Index: squid3/src/Makefile.am
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/Makefile.am,v
retrieving revision 1.26.2.35
retrieving revision 1.26.2.36
diff -u -r1.26.2.35 -r1.26.2.36
--- squid3/src/Makefile.am	24 Dec 2004 08:40:07 -0000	1.26.2.35
+++ squid3/src/Makefile.am	26 Dec 2004 09:24:13 -0000	1.26.2.36
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.am,v 1.26.2.35 2004/12/24 08:40:07 serassio Exp $
+#  $Id: Makefile.am,v 1.26.2.36 2004/12/26 09:24:13 serassio Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
@@ -175,7 +175,7 @@
 
 SUBDIRS		= fs repl auth
 
-EXTRA_LIBRARIES = libAIO.a libBlocking.a libDiskDaemon.a libDiskThreads.a
+EXTRA_LIBRARIES = libAIO.a libWinAIO.a libBlocking.a libDiskDaemon.a libDiskThreads.a
 noinst_LIBRARIES = @DISK_LIBS@
 
 INCLUDES        = $(MINGWINCLUDES) -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)/lib/libTrie/include
@@ -213,7 +213,6 @@
 cachemgr__CGIEXT__SOURCES = cachemgr.cc
 
 all_FSMODULES = \
-	fs/awin32/StoreFSawin32.cc \
 	fs/aufs/StoreFSaufs.cc \
 	fs/coss/StoreFScoss.cc \
 	fs/diskd/StoreFSdiskd.cc \
@@ -222,6 +221,7 @@
 
 all_DISKIOMODULES = \
 	DiskIO/AIO/AIODiskIOModule.cc \
+	DiskIO/WinAIO/WinAIODiskIOModule.cc \
 	DiskIO/Blocking/BlockingDiskIOModule.cc \
 	DiskIO/DiskDaemon/DiskDaemonDiskIOModule.cc \
 	DiskIO/DiskThreads/DiskThreadsDiskIOModule.cc
@@ -802,6 +802,16 @@
 		DiskIO/AIO/AIODiskIOStrategy.h \
 		DiskIO/AIO/AIODiskIOModule.h 
 
+libWinAIO_a_SOURCES = \
+		DiskIO/WinAIO/async_io.h \
+		DiskIO/WinAIO/Winaio.h \
+		DiskIO/WinAIO/Winaio.cc \
+		DiskIO/WinAIO/WinAIODiskFile.cc \
+		DiskIO/WinAIO/WinAIODiskFile.h \
+		DiskIO/WinAIO/WinAIODiskIOStrategy.cc \
+		DiskIO/WinAIO/WinAIODiskIOStrategy.h \
+		DiskIO/WinAIO/WinAIODiskIOModule.h 
+
 libBlocking_a_SOURCES = \
 		DiskIO/Blocking/BlockingFile.cc \
 		DiskIO/Blocking/BlockingFile.h \
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/src/DiskIO/WinAIO/WinAIODiskFile.cc	Wed Feb 14 13:34:01 2007
@@ -0,0 +1,255 @@
+
+/*
+ * $Id: WinAIODiskFile.cc,v 1.1.2.1 2004/12/26 09:23:30 serassio Exp $
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+/*
+ * Author: Adrian Chadd <adrian@squid-cache.org>
+ *
+ * These routines are simple plugin replacements for the file_* routines
+ * in disk.c . They back-end into the POSIX AIO routines to provide
+ * a nice and simple async IO framework for COSS.
+ *
+ * AIO is suitable for COSS - the only sync operations that the standard
+ * supports are read/write, and since COSS works on a single file
+ * per storedir it should work just fine.
+ */
+
+#include "squid.h"
+#include "WinAIODiskFile.h"
+#include "WinAIODiskIOStrategy.h"
+#include "DiskIO/IORequestor.h"
+#include "DiskIO/ReadRequest.h"
+#include "DiskIO/WriteRequest.h"
+
+CBDATA_CLASS_INIT(WinAIODiskFile);
+void *
+WinAIODiskFile::operator new (size_t)
+{
+    CBDATA_INIT_TYPE(WinAIODiskFile);
+    return cbdataAlloc(WinAIODiskFile);
+}
+
+void
+WinAIODiskFile::operator delete (void *address)
+{
+    cbdataFree(address);
+}
+
+WinAIODiskFile::WinAIODiskFile (char const *aPath, WinAIODiskIOStrategy *aStrategy) : fd(-1), closed(true), error_(false)
+{
+    assert (aPath);
+    path = aPath;
+    strategy = aStrategy;
+    debug (79,3)("WinAIODiskFile::WinAIODiskFile: %s\n", aPath);
+}
+
+WinAIODiskFile::~WinAIODiskFile()
+{}
+
+void
+WinAIODiskFile::error(bool const &aBool)
+{
+    error_ = aBool;
+}
+
+void
+WinAIODiskFile::open (int flags, mode_t mode, IORequestor::Pointer callback)
+{
+    /* Simulate async calls */
+    fd = aio_open(path.buf(), flags);
+    ioRequestor = callback;
+
+    if (fd < 0) {
+        debug(79, 3) ("WinAIODiskFile::open: got failure (%d)\n", errno);
+        error(true);
+    } else {
+        closed = false;
+        store_open_disk_fd++;
+        debug(79, 3) ("WinAIODiskFile::open: opened FD %d\n", fd);
+    }
+
+    callback->ioCompletedNotification();
+}
+
+void
+WinAIODiskFile::create (int flags, mode_t mode, RefCount<IORequestor> callback)
+{
+    /* We use the same logic path for open */
+    open(flags, mode, callback);
+}
+
+void
+WinAIODiskFile::read(ReadRequest *request)
+{
+    int slot;
+    async_queue_entry_t *qe;
+
+    assert(strategy->aq.aq_state == AQ_STATE_SETUP);
+
+    /* Find a free slot */
+    slot = strategy->findSlot();
+
+    if (slot < 0) {
+        /* No free slot? Callback error, and return */
+        fatal("Aiee! out of aiocb slots! - FIXME and wrap file_read\n");
+        debug(79, 1) ("WARNING: out of aiocb slots!\n");
+        return;
+    }
+
+    /* Mark slot as ours */
+    qe = &strategy->aq.aq_queue[slot];
+
+    qe->aq_e_state = AQ_ENTRY_USED;
+
+    qe->aq_e_callback_data = cbdataReference(request);
+
+    qe->theFile = cbdataReference(this);
+
+    qe->aq_e_type = AQ_ENTRY_READ;
+
+    qe->aq_e_free = NULL;
+
+    qe->aq_e_buf =  request->buf;
+
+    qe->aq_e_fd = getFD();
+
+    qe->aq_e_aiocb.aio_fildes = getFD();
+
+    qe->aq_e_aiocb.aio_nbytes = request->len;
+
+    qe->aq_e_aiocb.aio_offset =  request->offset;
+
+    qe->aq_e_aiocb.aio_buf =  request->buf;
+
+    /* Account */
+    strategy->aq.aq_numpending++;
+
+    /* Initiate aio */
+    if (aio_read(&qe->aq_e_aiocb) < 0) {
+        fatalf("Aiee! aio_read() returned error (%d)  FIXME and wrap file_read !\n", errno);
+        debug(79, 1) ("WARNING: aio_read() returned error: %s\n", xstrerror());
+     }
+
+}
+
+void
+WinAIODiskFile::write(WriteRequest *request)
+{
+    int slot;
+    async_queue_entry_t *qe;
+
+    assert(strategy->aq.aq_state == AQ_STATE_SETUP);
+
+    /* Find a free slot */
+    slot = strategy->findSlot();
+
+    if (slot < 0) {
+        /* No free slot? Callback error, and return */
+        fatal("Aiee! out of aiocb slots FIXME and wrap file_write !\n");
+        debug(79, 1) ("WARNING: out of aiocb slots!\n");
+        return;
+    }
+
+    /* Mark slot as ours */
+    qe = &strategy->aq.aq_queue[slot];
+
+    qe->aq_e_state = AQ_ENTRY_USED;
+
+    qe->aq_e_callback_data = cbdataReference(request);
+
+    qe->theFile = cbdataReference(this);
+
+    qe->aq_e_type = AQ_ENTRY_WRITE;
+
+    qe->aq_e_free = request->free_func;
+
+    qe->aq_e_buf = (void *)request->buf;
+
+    qe->aq_e_fd = fd;
+
+    qe->aq_e_aiocb.aio_fildes = fd;
+
+    qe->aq_e_aiocb.aio_nbytes = request->len;
+
+    qe->aq_e_aiocb.aio_offset = request->offset;
+
+    qe->aq_e_aiocb.aio_buf = (void *)request->buf;
+
+    /* Account */
+    ++strategy->aq.aq_numpending;
+
+    /* Initiate aio */
+    if (aio_write(&qe->aq_e_aiocb) < 0) {
+        fatalf("Aiee! aio_read() returned error (%d) FIXME and wrap file_write !\n", errno);
+        debug(79, 1) ("WARNING: aio_write() returned error: %s\n", xstrerror());
+    }
+}
+
+void
+WinAIODiskFile::close ()
+{
+    assert (!closed);
+    aio_close(fd);
+    fd = -1;
+    closed = true;
+    assert (ioRequestor.getRaw());
+    ioRequestor->closeCompleted();
+}
+
+bool
+WinAIODiskFile::canRead() const
+{
+    return true;
+}
+
+bool
+WinAIODiskFile::canWrite() const
+{
+    return true;
+}
+
+int
+WinAIODiskFile::getFD() const
+{
+    return fd;
+}
+
+bool
+WinAIODiskFile::error() const
+{
+    return error_;
+}
+
+bool
+WinAIODiskFile::ioInProgress() const
+{
+    return false;
+}
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/src/DiskIO/WinAIO/WinAIODiskFile.h	Wed Feb 14 13:34:01 2007
@@ -0,0 +1,79 @@
+
+/*
+ * $Id: WinAIODiskFile.h,v 1.1.2.1 2004/12/26 09:23:30 serassio Exp $
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_WINAIODISKFILE_H
+#define SQUID_WINAIODISKFILE_H
+
+#include "DiskIO/DiskFile.h"
+#include "async_io.h"
+
+class WinAIODiskIOStrategy;
+
+class WinAIODiskFile : public DiskFile
+{
+
+public:
+
+    friend class WinAIODiskIOStrategy;
+    void * operator new (size_t);
+    void operator delete (void *);
+    WinAIODiskFile (char const *path, WinAIODiskIOStrategy *);
+    ~WinAIODiskFile();
+    virtual void open (int, mode_t, RefCount<IORequestor>);
+    virtual void create (int, mode_t, RefCount<IORequestor>);
+    virtual void read(ReadRequest *);
+    virtual void write(WriteRequest *);
+    virtual void close ();
+    virtual bool canRead() const;
+    virtual bool canWrite() const;
+
+    /* During migration only */
+    virtual int getFD() const;
+
+    virtual bool error() const;
+
+    /* Inform callers if there is IO in progress */
+    virtual bool ioInProgress() const;
+
+private:
+    CBDATA_CLASS(WinAIODiskFile);
+    void error(bool const &);
+    int fd;
+    String path;
+    WinAIODiskIOStrategy *strategy;
+    RefCount<IORequestor> ioRequestor;
+    bool closed;
+    bool error_;
+};
+
+#endif /* SQUID_WINAIODISKFILE_H */
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/src/DiskIO/WinAIO/WinAIODiskIOModule.cc	Wed Feb 14 13:34:01 2007
@@ -0,0 +1,70 @@
+
+/*
+ * $Id: WinAIODiskIOModule.cc,v 1.1.2.1 2004/12/26 09:23:30 serassio Exp $
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "squid.h"
+#include "WinAIODiskIOModule.h"
+#include "WinAIODiskIOStrategy.h"
+#include "Store.h"
+
+WinAIODiskIOModule::WinAIODiskIOModule()
+{
+    ModuleAdd(*this);
+}
+
+WinAIODiskIOModule &
+WinAIODiskIOModule::GetInstance()
+{
+    return Instance;
+}
+
+void
+WinAIODiskIOModule::init()
+{}
+
+void
+WinAIODiskIOModule::shutdown()
+{}
+
+DiskIOStrategy *
+WinAIODiskIOModule::createStrategy()
+{
+    return new WinAIODiskIOStrategy();
+}
+
+WinAIODiskIOModule WinAIODiskIOModule::Instance;
+
+char const *
+WinAIODiskIOModule::type () const
+{
+    return "WinAIO";
+}
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/src/DiskIO/WinAIO/WinAIODiskIOModule.h	Wed Feb 14 13:34:01 2007
@@ -0,0 +1,54 @@
+
+/*
+ * $Id: WinAIODiskIOModule.h,v 1.1.2.1 2004/12/26 09:23:30 serassio Exp $
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_WINAIODISKIOMODULE_H
+#define SQUID_WINAIODISKIOMODULE_H
+
+#include "DiskIO/DiskIOModule.h"
+
+class WinAIODiskIOModule : public DiskIOModule
+{
+
+public:
+    static WinAIODiskIOModule &GetInstance();
+    WinAIODiskIOModule();
+    virtual void init();
+    virtual void shutdown();
+    virtual char const *type () const;
+    virtual DiskIOStrategy* createStrategy();
+
+private:
+    static WinAIODiskIOModule Instance;
+};
+
+#endif /* SQUID_WINAIODISKIOMODULE_H */
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/src/DiskIO/WinAIO/WinAIODiskIOStrategy.cc	Wed Feb 14 13:34:01 2007
@@ -0,0 +1,229 @@
+
+/*
+ * $Id: WinAIODiskIOStrategy.cc,v 1.1.2.1 2004/12/26 09:23:30 serassio Exp $
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+/*
+ * Author: Adrian Chadd <adrian@squid-cache.org>
+ *
+ * These routines are simple plugin replacements for the file_* routines
+ * in disk.c . They back-end into the POSIX AIO routines to provide
+ * a nice and simple async IO framework for COSS.
+ *
+ * AIO is suitable for COSS - the only sync operations that the standard
+ * supports are read/write, and since COSS works on a single file
+ * per storedir it should work just fine.
+ */
+
+#include "squid.h"
+#include "WinAIODiskIOStrategy.h"
+#include "WinAIODiskFile.h"
+#include "DiskIO/IORequestor.h"
+#include "DiskIO/ReadRequest.h"
+#include "DiskIO/WriteRequest.h"
+
+WinAIODiskIOStrategy::WinAIODiskIOStrategy()
+{
+    aq.aq_numpending = 0;
+}
+
+WinAIODiskIOStrategy::~WinAIODiskIOStrategy()
+{
+    assert(aq.aq_state == AQ_STATE_SETUP ||
+           aq.aq_numpending == 0);
+
+    sync();
+    aq.aq_state = AQ_STATE_NONE;
+}
+
+bool
+WinAIODiskIOStrategy::shedLoad()
+{
+    return false;
+}
+
+int
+WinAIODiskIOStrategy::load()
+{
+    return aq.aq_numpending * 1000 / MAX_ASYNCOP;
+}
+
+RefCount<DiskFile>
+WinAIODiskIOStrategy::newFile (char const *path)
+{
+    if (shedLoad()) {
+        return NULL;
+    }
+
+    return new WinAIODiskFile (path, this);
+}
+
+void
+WinAIODiskIOStrategy::sync()
+{
+    assert(aq.aq_state == AQ_STATE_SETUP);
+
+    /*
+     * Keep calling callback to complete ops until the queue is empty
+     * We can't quit when callback returns 0 - some calls may not
+     * return any completed pending events, but they're still pending!
+     */
+
+    while (aq.aq_numpending)
+        callback();
+}
+
+void
+WinAIODiskIOStrategy::unlinkFile (char const *)
+{}
+
+/*
+ * Note: we grab the state and free the state before calling the callback
+ * because this allows us to cut down the amount of time it'll take
+ * to find a free slot (since if we call the callback first, we're going
+ * to probably be allocated the slot _after_ this one..)
+ *
+ * I'll make it much more optimal later.
+ */
+int
+WinAIODiskIOStrategy::callback()
+{
+    return 0;
+    int i;
+    int completed = 0;
+    int retval, reterr;
+    FREE *freefunc;
+    void *cbdata;
+    int callback_valid;
+    void *buf;
+    int fd;
+    async_queue_entry_t *aqe;
+    async_queue_entry_type_t type;
+
+    assert(aq.aq_state == AQ_STATE_SETUP);
+
+    /* Loop through all slots */
+
+    for (i = 0; i < MAX_ASYNCOP; i++) {
+        if (aq.aq_queue[i].aq_e_state == AQ_ENTRY_USED) {
+            aqe = &aq.aq_queue[i];
+            /* Active, get status */
+            reterr = aio_error(&aqe->aq_e_aiocb);
+
+            if (reterr < 0) {
+                fatal("aio_error returned an error!\n");
+            }
+
+            if (reterr != EINPROGRESS) {
+                /* Get the return code */
+                retval = aio_return(&aqe->aq_e_aiocb);
+
+                /* Get the callback parameters */
+                freefunc = aqe->aq_e_free;
+                buf = aqe->aq_e_buf;
+                fd = aqe->aq_e_fd;
+                type = aqe->aq_e_type;
+                callback_valid = cbdataReferenceValidDone(aqe->aq_e_callback_data, &cbdata);
+                WinAIODiskFile * theFile = NULL;
+                void *theFileVoid = NULL;
+                bool fileOk = cbdataReferenceValidDone(aqe->theFile, &theFileVoid);
+
+                if (fileOk) {
+                    theFile = static_cast<WinAIODiskFile *>(theFileVoid);
+                }
+
+                /* Free slot */
+                bzero(aqe, sizeof(async_queue_entry_t));
+
+                aqe->aq_e_state = AQ_ENTRY_FREE;
+
+                --aq.aq_numpending;
+
+                /* Callback */
+
+                if (callback_valid) {
+                    assert (fileOk);
+
+                    if (type == AQ_ENTRY_READ)
+                        theFile->ioRequestor->readCompleted((const char *)buf, retval, reterr, static_cast<ReadRequest *>(cbdata));
+
+                    if (type == AQ_ENTRY_WRITE)
+                        theFile->ioRequestor->writeCompleted(reterr,retval, static_cast<WriteRequest *>(cbdata));
+                }
+
+                if (type == AQ_ENTRY_WRITE && freefunc)
+                    freefunc(buf);
+            }
+        }
+    }
+
+    return completed;
+}
+
+void
+WinAIODiskIOStrategy::init()
+{
+    /* Make sure the queue isn't setup */
+    assert(aq.aq_state == AQ_STATE_NONE);
+
+    /* Loop through, blanking the queue entries */
+
+    /* Done */
+    aq.aq_state = AQ_STATE_SETUP;
+}
+
+void
+WinAIODiskIOStrategy::statfs(StoreEntry & sentry)const
+    {}
+
+ConfigOption *
+WinAIODiskIOStrategy::getOptionTree() const
+{
+    return NULL;
+}
+
+/*
+ * find a free aio slot.
+ * Return the index, or -1 if we can't find one.
+ */
+int
+WinAIODiskIOStrategy::findSlot()
+{
+    /* Later we should use something a little more .. efficient :) */
+
+    for (int i = 0; i < MAX_ASYNCOP; i++) {
+        if (aq.aq_queue[i].aq_e_state == AQ_ENTRY_FREE)
+            /* Found! */
+            return i;
+    }
+
+    /* found nothing */
+    return -1;
+}
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/src/DiskIO/WinAIO/WinAIODiskIOStrategy.h	Wed Feb 14 13:34:01 2007
@@ -0,0 +1,75 @@
+
+/*
+ * $Id: WinAIODiskIOStrategy.h,v 1.1.2.1 2004/12/26 09:23:30 serassio Exp $
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_WINAIODISKIOSTRATEGY_H
+#define SQUID_WINAIODISKIOSTRATEGY_H
+
+#include "DiskIO/DiskIOStrategy.h"
+#include "async_io.h"
+
+class WinAIODiskIOStrategy : public DiskIOStrategy
+{
+
+public:
+    WinAIODiskIOStrategy();
+    virtual ~WinAIODiskIOStrategy();
+
+    virtual bool shedLoad();
+    /* What is the current load? 999 = 99.9% */
+    virtual int load();
+    /* Return a handle for performing IO operations */
+    virtual RefCount<DiskFile> newFile (char const *path);
+    /* flush all IO operations  */
+    virtual void sync();
+    /* unlink a file by path */
+    virtual void unlinkFile (char const *);
+
+    /* perform any pending callbacks */
+    virtual int callback();
+
+    /* Init per-instance logic */
+    virtual void init();
+
+    /* cachemgr output on the IO instance stats */
+    virtual void statfs(StoreEntry & sentry)const;
+    /* module specific options */
+    virtual ConfigOption *getOptionTree() const;
+    /* a file descriptor */
+    int fd;
+    /* queue of requests */
+    async_queue_t aq;
+
+    int findSlot();
+};
+
+#endif /* SQUID_WINAIODISKIOSTRATEGY_H */
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/src/DiskIO/WinAIO/Winaio.cc	Wed Feb 14 13:34:01 2007
@@ -0,0 +1,308 @@
+
+/*
+ * $Id: Winaio.cc,v 1.1.2.1 2004/12/26 09:23:30 serassio Exp $
+ *
+ * DEBUG: section 81    aio_xxx() POSIX emulation on WIN32 for COSS
+ * AUTHOR: Guido Serassio
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+#include "Winaio.h"
+
+#ifdef _SQUID_WIN32_
+VOID CALLBACK IoCompletionRoutine(DWORD dwErrorCode, 
+        DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped) 
+{ 
+    struct aiocb *aiocbp = (struct aiocb *) lpOverlapped->hEvent;
+
+    aiocbp->aio_sigevent.sigev_notify = dwErrorCode;
+    aiocbp->aio_sigevent.sigev_signo = dwNumberOfBytesTransfered;
+    debug(81,7) ("AIO operation complete: errorcode=%ld nbytes=%ld\n", dwErrorCode, dwNumberOfBytesTransfered);
+    xfree(lpOverlapped); 
+} 
+
+
+int aio_read(struct aiocb *aiocbp)
+{
+    LPOVERLAPPED Overlapped;
+    BOOL IoOperationStatus; 
+
+    /* Allocate an overlapped structure. */
+    Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED)); 
+    if (!Overlapped) { 
+	errno = ENOMEM; 
+        return -1; 
+    } 
+
+#if _FILE_OFFSET_BITS==64
+#ifdef __GNUC__
+    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
+    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
+#else
+    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
+    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
+#endif 
+#else
+    Overlapped->Offset = aiocbp->aio_offset; 
+    Overlapped->OffsetHigh = 0;
+#endif
+    Overlapped->hEvent = aiocbp;
+    aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
+    aiocbp->aio_sigevent.sigev_signo = -1;
+
+    IoOperationStatus = ReadFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
+				    aiocbp->aio_buf, 
+				    aiocbp->aio_nbytes, 
+				    Overlapped,
+				    IoCompletionRoutine); 
+
+    /* Test to see if the I/O was queued successfully. */
+    if (!IoOperationStatus) {
+	errno = GetLastError(); 
+	debug(81,1) ("aio_read: GetLastError=%i\n", errno);
+        return -1; 
+    }
+
+    /* The I/O queued successfully. Go back into the 
+       alertable wait for I/O completion or for 
+       more I/O requests. */
+    return 0;
+}
+
+
+int aio_read64(struct aiocb64 *aiocbp)
+{
+    LPOVERLAPPED Overlapped;
+    BOOL IoOperationStatus; 
+
+    /* Allocate an overlapped structure. */
+    Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED)); 
+    if (!Overlapped) { 
+	errno = ENOMEM; 
+        return -1; 
+    } 
+
+#ifdef __GNUC__
+    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
+    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
+#else
+    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
+    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
+#endif
+    Overlapped->hEvent = aiocbp;
+    aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
+    aiocbp->aio_sigevent.sigev_signo = -1;
+
+    IoOperationStatus = ReadFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
+				    aiocbp->aio_buf, 
+				    aiocbp->aio_nbytes, 
+				    Overlapped,
+				    IoCompletionRoutine); 
+
+    /* Test to see if the I/O was queued successfully. */
+    if (!IoOperationStatus) {
+	errno = GetLastError(); 
+	debug(81,1) ("aio_read: GetLastError=%i\n", errno);
+        return -1; 
+    }
+
+    /* The I/O queued successfully. Go back into the 
+       alertable wait for I/O completion or for 
+       more I/O requests. */
+    return 0;
+}
+
+
+int aio_write(struct aiocb *aiocbp)
+
+{
+    LPOVERLAPPED Overlapped;
+    BOOL IoOperationStatus; 
+
+    /* Allocate an overlapped structure. */
+    Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED)); 
+    if (!Overlapped) { 
+	errno = ENOMEM; 
+        return -1; 
+    } 
+#if _FILE_OFFSET_BITS==64
+#ifdef __GNUC__
+    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
+    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
+#else
+    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
+    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
+#endif
+#else
+    Overlapped->Offset = aiocbp->aio_offset; 
+    Overlapped->OffsetHigh = 0;
+#endif
+    Overlapped->hEvent = aiocbp;
+    aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
+    aiocbp->aio_sigevent.sigev_signo = -1;
+
+    IoOperationStatus = WriteFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
+				    aiocbp->aio_buf, 
+				    aiocbp->aio_nbytes, 
+				    Overlapped,
+				    IoCompletionRoutine); 
+ 
+    /* Test to see if the I/O was queued successfully. */
+    if (!IoOperationStatus) {
+	errno = GetLastError(); 
+	debug(81,1) ("aio_write: GetLastError=%i\n", errno);
+        return -1; 
+    }
+
+    /* The I/O queued successfully. Go back into the 
+       alertable wait for I/O completion or for 
+       more I/O requests. */
+    return 0;
+}
+
+
+int aio_write64(struct aiocb64 *aiocbp)
+
+{
+    LPOVERLAPPED Overlapped;
+    BOOL IoOperationStatus; 
+
+    /* Allocate an overlapped structure. */
+    Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED)); 
+    if (!Overlapped) { 
+	errno = ENOMEM; 
+        return -1; 
+    } 
+#ifdef __GNUC__
+    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
+    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
+#else
+    Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
+    Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
+#endif
+    Overlapped->hEvent = aiocbp;
+    aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
+    aiocbp->aio_sigevent.sigev_signo = -1;
+
+    IoOperationStatus = WriteFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
+				    aiocbp->aio_buf, 
+				    aiocbp->aio_nbytes, 
+				    Overlapped,
+				    IoCompletionRoutine); 
+ 
+    /* Test to see if the I/O was queued successfully. */
+    if (!IoOperationStatus) {
+	errno = GetLastError(); 
+	debug(81,1) ("aio_write: GetLastError=%i\n", errno);
+        return -1; 
+    }
+
+    /* The I/O queued successfully. Go back into the 
+       alertable wait for I/O completion or for 
+       more I/O requests. */
+    return 0;
+}
+
+
+ssize_t aio_return(struct aiocb * aiocbp)
+
+{
+    return aiocbp->aio_sigevent.sigev_signo;
+}
+
+
+ssize_t aio_return64(struct aiocb64 * aiocbp)
+
+{
+    return aiocbp->aio_sigevent.sigev_signo;
+}
+
+
+int aio_error(const struct aiocb * aiocbp)
+
+{
+    return aiocbp->aio_sigevent.sigev_notify;
+}
+
+
+int aio_error64(const struct aiocb64 * aiocbp)
+
+{
+    return aiocbp->aio_sigevent.sigev_notify;
+}
+
+
+int aio_open(const char *path, int mode)
+{
+    HANDLE hndl;
+    DWORD dwCreationDisposition;
+    DWORD dwDesiredAccess;
+    int fd;
+
+    if (mode & O_WRONLY)
+	mode |= O_APPEND;
+    mode |= O_BINARY;
+    errno = 0;
+    if (mode & O_WRONLY)
+        dwDesiredAccess = GENERIC_WRITE;
+    else
+	dwDesiredAccess = (mode & O_RDONLY) ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE;
+    if (mode & O_TRUNC)
+        dwCreationDisposition = CREATE_ALWAYS;
+    else
+	dwCreationDisposition = (mode & O_CREAT) ? OPEN_ALWAYS : OPEN_EXISTING;
+
+    if ((hndl = CreateFile(path,	/* file name               */
+		dwDesiredAccess,	/* access mode             */
+		0,			/* share mode              */
+		NULL,			/* SD                      */
+		dwCreationDisposition,	/* how to create           */
+		FILE_FLAG_OVERLAPPED,	/* file attributes         */
+		NULL			/* handle to template file */
+		)) != INVALID_HANDLE_VALUE) {
+	statCounter.syscalls.disk.opens++;
+	fd = _open_osfhandle((long) hndl, 0);
+	commSetCloseOnExec(fd);
+	fd_open(fd, FD_FILE, path);
+    } else {
+	errno = GetLastError();
+	fd = DISK_ERROR;
+    }
+    return fd;
+}
+
+
+void aio_close(int fd)
+{
+    CloseHandle((HANDLE)_get_osfhandle(fd));
+    fd_close(fd);
+    statCounter.syscalls.disk.closes++;
+}
+#endif
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/src/DiskIO/WinAIO/Winaio.h	Wed Feb 14 13:34:01 2007
@@ -0,0 +1,58 @@
+#ifndef __WIN32_AIO_H__
+#define __WIN32_AIO_H__
+
+#ifdef _SQUID_CYGWIN_
+#include <windows.h>
+#endif
+
+#ifndef off64_t
+typedef int64_t	off64_t;
+#endif
+
+union sigval {
+    int sival_int; /* integer value */
+    void *sival_ptr; /* pointer value */
+};
+
+struct sigevent {
+    int sigev_notify; /* notification mode */
+    int sigev_signo; /* signal number */
+    union sigval sigev_value; /* signal value */
+};
+
+struct aiocb64 {
+    int aio_fildes; /* file descriptor */
+    void *aio_buf; /* buffer location */
+    size_t aio_nbytes; /* length of transfer */
+    off64_t aio_offset; /* file offset */
+    int aio_reqprio; /* request priority offset */
+    struct sigevent aio_sigevent; /* signal number and offset */
+    int aio_lio_opcode; /* listio operation */
+};
+
+struct aiocb {
+    int aio_fildes; /* file descriptor */
+    void *aio_buf; /* buffer location */
+    size_t aio_nbytes; /* length of transfer */
+#if (_FILE_OFFSET_BITS == 64)
+    off64_t aio_offset; /* file offset */
+#else
+    off_t aio_offset; /* file offset */
+#endif
+    int aio_reqprio; /* request priority offset */
+    struct sigevent aio_sigevent; /* signal number and offset */
+    int aio_lio_opcode; /* listio operation */
+};
+
+int aio_read(struct aiocb *);
+int aio_write(struct aiocb *);
+ssize_t aio_return(struct aiocb *);
+int aio_error(const struct aiocb *);
+int aio_read64(struct aiocb64 *);
+int aio_write64(struct aiocb64 *);
+ssize_t aio_return64(struct aiocb64 *);
+int aio_error64(const struct aiocb64 *);
+int aio_open(const char *, int);
+void aio_close(int);
+
+#endif
--- /dev/null	Wed Feb 14 13:33:00 2007
+++ squid3/src/DiskIO/WinAIO/async_io.h	Wed Feb 14 13:34:01 2007
@@ -0,0 +1,54 @@
+#ifndef __ASYNC_IO_H__
+#define __ASYNC_IO_H__
+#include "Winaio.h"
+
+#define MAX_ASYNCOP		128
+
+typedef enum {
+    AQ_STATE_NONE,		/* Not active/uninitialised */
+    AQ_STATE_SETUP		/* Initialised */
+} async_queue_state_t;
+
+typedef enum {
+    AQ_ENTRY_FREE,
+    AQ_ENTRY_USED
+} async_queue_entry_state_t;
+
+typedef enum {
+    AQ_ENTRY_NONE,
+    AQ_ENTRY_READ,
+    AQ_ENTRY_WRITE
+} async_queue_entry_type_t;
+
+
+typedef struct _async_queue_entry async_queue_entry_t;
+
+typedef struct _async_queue async_queue_t;
+
+/* An async queue entry */
+
+class WinAIODiskFile;
+
+struct _async_queue_entry
+{
+    async_queue_entry_state_t aq_e_state;
+    async_queue_entry_type_t aq_e_type;
+
+    struct aiocb aq_e_aiocb;
+    WinAIODiskFile *theFile;
+    void *aq_e_callback_data;
+    FREE *aq_e_free;
+    int aq_e_fd;
+    void *aq_e_buf;
+};
+
+/* An async queue */
+
+struct _async_queue
+{
+    async_queue_state_t aq_state;
+    async_queue_entry_t aq_queue[MAX_ASYNCOP];	/* queued ops */
+    int aq_numpending;		/* Num of pending ops */
+};
+
+#endif
