]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Windows port: Added Windows Overlapped I/O support to AIO Disk module
authorserassio <>
Tue, 5 Sep 2006 02:15:21 +0000 (02:15 +0000)
committerserassio <>
Tue, 5 Sep 2006 02:15:21 +0000 (02:15 +0000)
configure.in
src/DiskIO/AIO/AIODiskFile.cc
src/DiskIO/AIO/aio_win32.cc [new file with mode: 0755]
src/DiskIO/AIO/aio_win32.h [new file with mode: 0755]
src/DiskIO/AIO/async_io.h
src/Makefile.am

index ba4d0e3fe20edc799150d01f758fc9faaa4ea02a..7311d4b0fc43c50d900648c634590700b7a6c730 100644 (file)
@@ -1,7 +1,7 @@
 
 dnl  Configuration input file for Squid
 dnl
-dnl  $Id: configure.in,v 1.434 2006/09/03 18:47:17 serassio Exp $
+dnl  $Id: configure.in,v 1.435 2006/09/04 20:15:21 serassio Exp $
 dnl
 dnl
 dnl
@@ -11,7 +11,7 @@ AM_CONFIG_HEADER(include/autoconf.h)
 AC_CONFIG_AUX_DIR(cfgaux)
 AC_CONFIG_SRCDIR([src/main.cc])
 AM_INIT_AUTOMAKE([tar-ustar])
-AC_REVISION($Revision: 1.434 $)dnl
+AC_REVISION($Revision: 1.435 $)dnl
 AC_PREFIX_DEFAULT(/usr/local/squid)
 AM_MAINTAINER_MODE
 
@@ -607,31 +607,31 @@ for fs in $DISK_MODULES none; do
 done
 
 if test -z "$FOUND_BLOCKING" && test -n "$NEED_BLOCKING"; then
-   echo "adding Blocking, as it is used by an active, legacy Store Module"
-   DISK_LIBS="$DISK_LIBS libBlocking.a"
-   DISK_MODULES="$DISK_MODULES Blocking"
-   DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/Blocking/BlockingDiskIOModule.o"
+    echo "adding Blocking, as it is used by an active, legacy Store Module"
+    DISK_LIBS="$DISK_LIBS libBlocking.a"
+    DISK_MODULES="$DISK_MODULES Blocking"
+    DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/Blocking/BlockingDiskIOModule.o"
 fi
 
 if test -z "$FOUND_DISKDAEMON" && test -n "$NEED_DISKDAEMON"; then
-   echo "adding DiskDaemon, as it is used by an active, legacy Store Module"
-   DISK_LIBS="$DISK_LIBS libDiskDaemon.a"
-   DISK_MODULES="$DISK_MODULES DiskDaemon"
-   DISK_PROGRAMS="$DISK_PROGRAMS DiskIO/DiskDaemon/diskd"
-   DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/DiskDaemon/DiskDaemonDiskIOModule.o"
+    echo "adding DiskDaemon, as it is used by an active, legacy Store Module"
+    DISK_LIBS="$DISK_LIBS libDiskDaemon.a"
+    DISK_MODULES="$DISK_MODULES DiskDaemon"
+    DISK_PROGRAMS="$DISK_PROGRAMS DiskIO/DiskDaemon/diskd"
+    DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/DiskDaemon/DiskDaemonDiskIOModule.o"
 fi
 
 if test -z "$FOUND_DISKTHREADS" && test -n "$NEED_DISKTHREADS"; then
-   echo "adding DiskThreads, as it is used by an active, legacy Store Module"
-   DISK_LIBS="$DISK_LIBS libDiskThreads.a"
-   DISK_MODULES="$DISK_MODULES DiskThreads"
-   DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/DiskThreads/DiskThreadsDiskIOModule.o"
+    echo "adding DiskThreads, as it is used by an active, legacy Store Module"
+    DISK_LIBS="$DISK_LIBS libDiskThreads.a"
+    DISK_MODULES="$DISK_MODULES DiskThreads"
+    DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/DiskThreads/DiskThreadsDiskIOModule.o"
 fi
 if test -z "$FOUND_AIO" && test -n "$NEED_AIO"; then
-   echo "adding AIO, as it is used by an active, legacy Store Module"
-   DISK_LIBS="$DISK_LIBS libAIO.a"
-   DISK_MODULES="$DISK_MODULES AIO"
-   DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/AIO/AIODiskIOModule.o"
+    echo "adding AIO, as it is used by an active, legacy Store Module"
+    DISK_LIBS="$DISK_LIBS libAIO.a"
+    DISK_MODULES="$DISK_MODULES AIO"
+    DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/AIO/AIODiskIOModule.o"
 fi
 echo "IO Modules built: $DISK_MODULES"
 dnl we know what is being built. now add dependencies.
@@ -645,8 +645,17 @@ for fs in $DISK_MODULES none; do
        ;;
     AIO)
        if test -z "$with_aio"; then
-           echo "Aio IO Module used, aio support automatically enabled"
-           with_aio=yes
+            case "$host_os" in
+            mingw|mingw32|cygwin|cygwin32)
+               AM_CONDITIONAL(USE_AIO_WIN32, true)
+               echo "Aio IO Module used, Windows overlapped I/O support automatically enabled"
+                ;;
+            *)
+               AM_CONDITIONAL(USE_AIO_WIN32, false)
+               echo "Aio IO Module used, aio support automatically enabled"
+               with_aio=yes
+                ;;
+            esac
        fi
        ;;
     esac
index ff77f00444165a0d852d3fa64ba0db7606f7471a..b9de96d41a59e9c96224bb36b5a1e298565f9b3c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: AIODiskFile.cc,v 1.2 2006/05/31 17:23:02 wessels Exp $
+ * $Id: AIODiskFile.cc,v 1.3 2006/09/04 20:15:22 serassio Exp $
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
  * ----------------------------------------------------------
@@ -84,7 +84,13 @@ void
 AIODiskFile::open (int flags, mode_t mode, IORequestor::Pointer callback)
 {
     /* Simulate async calls */
+#ifdef _SQUID_WIN32_
+    fd = aio_open(path.buf(), flags);
+#else
+
     fd = file_open(path.buf() , flags);
+#endif
+
     ioRequestor = callback;
 
     if (fd < 0) {
@@ -214,7 +220,7 @@ AIODiskFile::write(WriteRequest *request)
 
     /* Initiate aio */
     if (aio_write(&qe->aq_e_aiocb) < 0) {
-        fatalf("Aiee! aio_read() returned error (%d) FIXME and wrap file_write !\n", errno);
+        fatalf("Aiee! aio_write() returned error (%d) FIXME and wrap file_write !\n", errno);
         debug(79, 1) ("WARNING: aio_write() returned error: %s\n", xstrerror());
         /* fall back to blocking method */
         //       file_write(fd, offset, buf, len, callback, data, freefunc);
@@ -225,7 +231,14 @@ void
 AIODiskFile::close ()
 {
     assert (!closed);
+#ifdef _SQUID_WIN32_
+
+    aio_close(fd);
+#else
+
     file_close(fd);
+#endif
+
     fd = -1;
     closed = true;
     assert (ioRequestor != NULL);
diff --git a/src/DiskIO/AIO/aio_win32.cc b/src/DiskIO/AIO/aio_win32.cc
new file mode 100755 (executable)
index 0000000..e9c0946
--- /dev/null
@@ -0,0 +1,362 @@
+
+/*
+ * $Id: aio_win32.cc,v 1.1 2006/09/04 20:15:22 serassio Exp $
+ *
+ * DEBUG: section 81    aio_xxx() POSIX emulation on Windows
+ * 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 "comm.h"
+#include "aio_win32.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 % 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 = 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;
+}
+
+
+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++;
+}
+
+
+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;
+}
+#endif /* _SQUID_WIN32_ */
diff --git a/src/DiskIO/AIO/aio_win32.h b/src/DiskIO/AIO/aio_win32.h
new file mode 100755 (executable)
index 0000000..733e3c3
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef __WIN32_AIO_H__
+#define __WIN32_AIO_H__
+
+#ifdef _SQUID_CYGWIN_
+#include "squid_windows.h"
+#endif
+
+#ifndef off64_t
+typedef int64_t        off64_t;
+#endif
+
+#ifdef _SQUID_MSWIN_
+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 */
+};
+
+#endif
+
+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
index f2ea778d0d0e550ba840f3ad9eebdca4357b12b6..9fff102dcd84c2f7f6975a6db74944aae1e1ed7b 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef __ASYNC_IO_H__
 #define __ASYNC_IO_H__
+#ifdef _SQUID_WIN32_
+#include "aio_win32.h"
+#else
 #include <aio.h>
+#endif
 
 #define MAX_ASYNCOP            128
 
index c4c231cc2610e0de8844c953049978dcac804425..93543804ed58e38329848eafa3ed9ca1f9d93970 100644 (file)
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.am,v 1.163 2006/09/03 18:47:18 serassio Exp $
+#  $Id: Makefile.am,v 1.164 2006/09/04 20:15:21 serassio Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
@@ -153,6 +153,15 @@ else
 IPC_SOURCE = ipc.cc
 endif
 
+AIO_WIN32_ALL_SOURCES = \
+       DiskIO/AIO/aio_win32.cc \
+       DiskIO/AIO/aio_win32.h
+if USE_AIO_WIN32
+AIO_WIN32_SOURCES = $(AIO_WIN32_ALL_SOURCES)
+else
+AIO_WIN32_SOURCES =
+endif
+
 IDENT_ALL_SOURCE = ACLIdent.cc ACLIdent.h ident.cc
 if ENABLE_IDENT
 IDENT_SOURCE = $(IDENT_ALL_SOURCE)
@@ -249,6 +258,7 @@ all_AUTHMODULES = \
 EXTRA_squid_SOURCES = \
        $(all_FSMODULES) \
        $(all_DISKIOMODULES) \
+       $(AIO_WIN32_ALL_SOURCES) \
        $(all_AUTHMODULES) \
        $(ARP_ACL_ALL_SOURCE) \
        ConfigOption.h \
@@ -904,6 +914,7 @@ EXTRA_DIST = \
        mime.conf.default
 
 libAIO_a_SOURCES = \
+               $(AIO_WIN32_SOURCES) \
                DiskIO/AIO/async_io.h \
                DiskIO/AIO/AIODiskFile.cc \
                DiskIO/AIO/AIODiskFile.h \