/*
- * $Id: aiops_win32.cc,v 1.1 2006/09/06 19:36:42 serassio Exp $
+ * $Id$
*
- * DEBUG: section 43 AIOPS
+ * DEBUG: section 43 Windows AIOPS
* AUTHOR: Stewart Forster <slf@connect.com.au>
+ * AUTHOR: Robert Collins <robertc@squid-cache.org>
+ * AUTHOR: Guido Serassio <serassio@squid-cache.org>
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
* 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 "squid_windows.h"
+#include "DiskIO/DiskThreads/CommIO.h"
#include "DiskThreads.h"
+#include "SquidTime.h"
+#include "Store.h"
#include <stdio.h>
-#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <signal.h>
-#include "CommIO.h"
-#include "SquidTime.h"
-#include "Store.h"
#define RIDICULOUS_LENGTH 4096
};
typedef enum _squidaio_thread_status squidaio_thread_status;
-typedef struct squidaio_request_t
-{
+typedef struct squidaio_request_t {
struct squidaio_request_t *next;
squidaio_request_type request_type;
int fd;
char *bufferp;
char *tmpbufp;
- int buflen;
+ size_t buflen;
off_t offset;
int whence;
int ret;
struct stat *statp;
squidaio_result_t *resultp;
-}
-
-squidaio_request_t;
+} squidaio_request_t;
-typedef struct squidaio_request_queue_t
-{
+typedef struct squidaio_request_queue_t {
HANDLE mutex;
HANDLE cond; /* See Event objects */
squidaio_request_t *volatile head;
squidaio_request_t *volatile *volatile tailp;
unsigned long requests;
unsigned long blocked; /* main failed to lock the queue */
-}
-
-squidaio_request_queue_t;
+} squidaio_request_queue_t;
typedef struct squidaio_thread_t squidaio_thread_t;
-struct squidaio_thread_t
-{
+struct squidaio_thread_t {
squidaio_thread_t *next;
HANDLE thread;
DWORD dwThreadId; /* thread ID */
static void squidaio_do_write(squidaio_request_t *);
static void squidaio_do_close(squidaio_request_t *);
static void squidaio_do_stat(squidaio_request_t *);
-#if USE_TRUNCATE
-static void squidaio_do_truncate(squidaio_request_t *);
-#else
static void squidaio_do_unlink(squidaio_request_t *);
-#endif
#if AIO_OPENDIR
static void *squidaio_do_opendir(squidaio_request_t *);
#endif
static squidaio_thread_t *threads = NULL;
static int squidaio_initialised = 0;
-
#define AIO_LARGE_BUFS 16384
#define AIO_MEDIUM_BUFS AIO_LARGE_BUFS >> 1
#define AIO_SMALL_BUFS AIO_LARGE_BUFS >> 2
static MemAllocator *squidaio_thread_pool = NULL;
static squidaio_request_queue_t request_queue;
-static struct
-{
+static struct {
squidaio_request_t *head, **tailp;
}
request_queue2 = {
- NULL, &request_queue2.head
- };
+ NULL, &request_queue2.head
+};
static squidaio_request_queue_t done_queue;
-static struct
-{
+static struct {
squidaio_request_t *head, **tailp;
}
done_requests = {
- NULL, &done_requests.head
- };
+ NULL, &done_requests.head
+};
static HANDLE main_thread;
assert(NUMTHREADS);
- for (i = 0; i < NUMTHREADS; i++) {
+ for (i = 0; i < NUMTHREADS; ++i) {
threadp = (squidaio_thread_t *)squidaio_thread_pool->alloc();
threadp->status = _THREAD_STARTING;
threadp->current_req = NULL;
threadp = threads;
- for (i = 0; i < NUMTHREADS; i++) {
+ for (i = 0; i < NUMTHREADS; ++i) {
threadp->exit = 1;
hthreads[i] = threadp->thread;
threadp = threadp->next;
WaitForMultipleObjects(NUMTHREADS, hthreads, TRUE, 2000);
- for (i = 0; i < NUMTHREADS; i++) {
+ for (i = 0; i < NUMTHREADS; ++i) {
CloseHandle(hthreads[i]);
}
squidaio_do_close(request);
break;
-#if USE_TRUNCATE
-
- case _AIO_OP_TRUNCATE:
- squidaio_do_truncate(request);
- break;
-#else
-
case _AIO_OP_UNLINK:
squidaio_do_unlink(request);
break;
-#endif
#if AIO_OPENDIR /* Opendir not implemented yet */
case _AIO_OP_OPENDIR:
CommIO::NotifyIOCompleted();
Sleep(0);
- threadp->requests++;
+ ++ threadp->requests;
} /* while forever */
CloseHandle(cond);
squidaio_queue_request(squidaio_request_t * request)
{
static int high_start = 0;
- debug(43, 9) ("squidaio_queue_request: %p type=%d result=%p\n",
- request, request->request_type, request->resultp);
+ debugs(43, 9, "squidaio_queue_request: " << request << " type=" << request->request_type << " result=" << request->resultp);
/* Mark it as not executed (failing result, no error) */
request->ret = -1;
request->err = 0;
if (++filter >= filter_limit) {
filter_limit += filter;
filter = 0;
- debug(43, 1) ("squidaio_queue_request: WARNING - Queue congestion\n");
+ debugs(43, DBG_IMPORTANT, "squidaio_queue_request: WARNING - Queue congestion");
}
}
if (squid_curtime >= (last_warn + 15) &&
squid_curtime >= (high_start + 5)) {
- debug(43, 1) ("squidaio_queue_request: WARNING - Disk I/O overloading\n");
+ debugs(43, DBG_IMPORTANT, "squidaio_queue_request: WARNING - Disk I/O overloading");
if (squid_curtime >= (high_start + 15))
- debug(43, 1) ("squidaio_queue_request: Queue Length: current=%d, high=%d, low=%d, duration=%ld\n",
- request_queue_len, queue_high, queue_low, (long int) (squid_curtime - high_start));
+ debugs(43, DBG_IMPORTANT, "squidaio_queue_request: Queue Length: current=" <<
+ request_queue_len << ", high=" << queue_high <<
+ ", low=" << queue_low << ", duration=" <<
+ (long int) (squid_curtime - high_start));
last_warn = (int)squid_curtime;
}
/* Warn if seriously overloaded */
if (request_queue_len > RIDICULOUS_LENGTH) {
- debug(43, 0) ("squidaio_queue_request: Async request queue growing uncontrollably!\n");
- debug(43, 0) ("squidaio_queue_request: Syncing pending I/O operations.. (blocking)\n");
+ debugs(43, DBG_CRITICAL, "squidaio_queue_request: Async request queue growing uncontrollably!");
+ debugs(43, DBG_CRITICAL, "squidaio_queue_request: Syncing pending I/O operations.. (blocking)");
squidaio_sync();
- debug(43, 0) ("squidaio_queue_request: Synced\n");
+ debugs(43, DBG_CRITICAL, "squidaio_queue_request: Synced");
}
} /* squidaio_queue_request */
case _AIO_OP_STAT:
if (!cancelled && requestp->ret == 0)
-
- xmemcpy(requestp->statp, requestp->tmpstatp, sizeof(struct stat));
+ memcpy(requestp->statp, requestp->tmpstatp, sizeof(struct stat));
squidaio_xfree(requestp->tmpstatp, sizeof(struct stat));
case _AIO_OP_UNLINK:
- case _AIO_OP_TRUNCATE:
-
case _AIO_OP_OPENDIR:
squidaio_xstrfree(requestp->path);
squidaio_request_pool->free(requestp);
} /* squidaio_cleanup_request */
-
int
squidaio_cancel(squidaio_result_t * resultp)
{
squidaio_request_t *request = (squidaio_request_t *)resultp->_data;
if (request && request->resultp == resultp) {
- debug(43, 9) ("squidaio_cancel: %p type=%d result=%p\n",
- request, request->request_type, request->resultp);
+ debugs(43, 9, "squidaio_cancel: " << request << " type=" << request->request_type << " result=" << request->resultp);
request->cancelled = 1;
request->resultp = NULL;
resultp->_data = NULL;
return 1;
} /* squidaio_cancel */
-
int
squidaio_open(const char *path, int oflag, mode_t mode, squidaio_result_t * resultp)
{
return 0;
}
-
static void
squidaio_do_open(squidaio_request_t * requestp)
{
requestp->err = errno;
}
-
int
-squidaio_read(int fd, char *bufp, int bufs, off_t offset, int whence, squidaio_result_t * resultp)
+squidaio_read(int fd, char *bufp, size_t bufs, off_t offset, int whence, squidaio_result_t * resultp)
{
squidaio_request_t *requestp;
return 0;
}
-
static void
squidaio_do_read(squidaio_request_t * requestp)
{
requestp->err = errno;
}
-
int
-squidaio_write(int fd, char *bufp, int bufs, off_t offset, int whence, squidaio_result_t * resultp)
+squidaio_write(int fd, char *bufp, size_t bufs, off_t offset, int whence, squidaio_result_t * resultp)
{
squidaio_request_t *requestp;
return 0;
}
-
static void
squidaio_do_write(squidaio_request_t * requestp)
{
requestp->err = errno;
}
-
int
squidaio_close(int fd, squidaio_result_t * resultp)
{
return 0;
}
-
static void
squidaio_do_close(squidaio_request_t * requestp)
{
- if((requestp->ret = close(requestp->fd)) < 0) {
- debug(43, 0) ("squidaio_do_close: FD %d, errno %d\n", requestp->fd, errno);
+ if ((requestp->ret = close(requestp->fd)) < 0) {
+ debugs(43, DBG_CRITICAL, "squidaio_do_close: FD " << requestp->fd << ", errno " << errno);
close(requestp->fd);
}
requestp->err = errno;
}
-
int
squidaio_stat(const char *path, struct stat *sb, squidaio_result_t * resultp)
return 0;
}
-
static void
squidaio_do_stat(squidaio_request_t * requestp)
{
requestp->err = errno;
}
-
-#if USE_TRUNCATE
-int
-squidaio_truncate(const char *path, off_t length, squidaio_result_t * resultp)
-{
- squidaio_init();
- squidaio_request_t *requestp;
-
- requestp = (squidaio_request_t *)squidaio_request_pool->alloc();
-
- requestp->path = (char *) squidaio_xstrdup(path);
-
- requestp->offset = length;
-
- requestp->resultp = resultp;
-
- requestp->request_type = _AIO_OP_TRUNCATE;
-
- requestp->cancelled = 0;
-
- resultp->result_type = _AIO_OP_TRUNCATE;
-
- squidaio_queue_request(requestp);
-
- return 0;
-}
-
-
-static void
-squidaio_do_truncate(squidaio_request_t * requestp)
-{
- requestp->ret = truncate(requestp->path, requestp->offset);
- requestp->err = errno;
-}
-
-
-#else
int
squidaio_unlink(const char *path, squidaio_result_t * resultp)
{
return 0;
}
-
static void
squidaio_do_unlink(squidaio_request_t * requestp)
{
requestp->err = errno;
}
-#endif
-
#if AIO_OPENDIR
/* XXX squidaio_opendir NOT implemented yet.. */
return NULL;
}
- debug(43, 9) ("squidaio_poll_done: %p type=%d result=%p\n",
- request, request->request_type, request->resultp);
+ debugs(43, 9, "squidaio_poll_done: " << request << " type=" << request->request_type << " result=" << request->resultp);
done_requests.head = request->next;
if (!done_requests.head)
squidaio_debug(request);
- debug(43, 5) ("DONE: %d -> %d\n", request->ret, request->err);
+ debugs(43, 5, "DONE: " << request->ret << " -> " << request->err);
squidaio_cleanup_request(request);
switch (request->request_type) {
case _AIO_OP_OPEN:
- debug(43, 5) ("OPEN of %s to FD %d\n", request->path, request->ret);
+ debugs(43, 5, "OPEN of " << request->path << " to FD " << request->ret);
break;
case _AIO_OP_READ:
- debug(43, 5) ("READ on fd: %d\n", request->fd);
+ debugs(43, 5, "READ on fd: " << request->fd);
break;
case _AIO_OP_WRITE:
- debug(43, 5) ("WRITE on fd: %d\n", request->fd);
+ debugs(43, 5, "WRITE on fd: " << request->fd);
break;
case _AIO_OP_CLOSE:
- debug(43, 5) ("CLOSE of fd: %d\n", request->fd);
+ debugs(43, 5, "CLOSE of fd: " << request->fd);
break;
case _AIO_OP_UNLINK:
- debug(43, 5) ("UNLINK of %s\n", request->path);
- break;
-
- case _AIO_OP_TRUNCATE:
- debug(43, 5) ("UNLINK of %s\n", request->path);
+ debugs(43, 5, "UNLINK of " << request->path);
break;
default:
threadp = threads;
- for (i = 0; i < NUMTHREADS; i++) {
+ for (i = 0; i < NUMTHREADS; ++i) {
storeAppendPrintf(sentry, "%i\t0x%lx\t%ld\n", i + 1, threadp->dwThreadId, threadp->requests);
threadp = threadp->next;
}