From: serassio <> Date: Tue, 5 Sep 2006 02:15:21 +0000 (+0000) Subject: Windows port: Added Windows Overlapped I/O support to AIO Disk module X-Git-Tag: SQUID_3_0_PRE5~110 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=abb2a3d970250c126c0bfb434e8b1eedd9c24059;p=thirdparty%2Fsquid.git Windows port: Added Windows Overlapped I/O support to AIO Disk module --- diff --git a/configure.in b/configure.in index ba4d0e3fe2..7311d4b0fc 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/src/DiskIO/AIO/AIODiskFile.cc b/src/DiskIO/AIO/AIODiskFile.cc index ff77f00444..b9de96d41a 100644 --- a/src/DiskIO/AIO/AIODiskFile.cc +++ b/src/DiskIO/AIO/AIODiskFile.cc @@ -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 index 0000000000..e9c0946d75 --- /dev/null +++ b/src/DiskIO/AIO/aio_win32.cc @@ -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 index 0000000000..733e3c3a04 --- /dev/null +++ b/src/DiskIO/AIO/aio_win32.h @@ -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 diff --git a/src/DiskIO/AIO/async_io.h b/src/DiskIO/AIO/async_io.h index f2ea778d0d..9fff102dcd 100644 --- a/src/DiskIO/AIO/async_io.h +++ b/src/DiskIO/AIO/async_io.h @@ -1,6 +1,10 @@ #ifndef __ASYNC_IO_H__ #define __ASYNC_IO_H__ +#ifdef _SQUID_WIN32_ +#include "aio_win32.h" +#else #include +#endif #define MAX_ASYNCOP 128 diff --git a/src/Makefile.am b/src/Makefile.am index c4c231cc26..93543804ed 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \