--------------------- 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 -#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 - -#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 + */ +/* + * Author: Adrian Chadd + * + * 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 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 + */ + +#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); + virtual void create (int, mode_t, RefCount); + 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; + 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 + */ + +#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 + */ + +#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 + */ +/* + * Author: Adrian Chadd + * + * 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 +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(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(cbdata)); + + if (type == AQ_ENTRY_WRITE) + theFile->ioRequestor->writeCompleted(reterr,retval, static_cast(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 + */ + +#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 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 +#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