3 * $Id: aio_win32.cc,v 1.1 2006/09/04 20:15:22 serassio Exp $
5 * DEBUG: section 81 aio_xxx() POSIX emulation on Windows
6 * AUTHOR: Guido Serassio
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
38 #include "aio_win32.h"
41 VOID CALLBACK
IoCompletionRoutine(DWORD dwErrorCode
,
42 DWORD dwNumberOfBytesTransfered
, LPOVERLAPPED lpOverlapped
)
45 struct aiocb
*aiocbp
= (struct aiocb
*) lpOverlapped
->hEvent
;
47 aiocbp
->aio_sigevent
.sigev_notify
= dwErrorCode
;
48 aiocbp
->aio_sigevent
.sigev_signo
= dwNumberOfBytesTransfered
;
49 debug(81,7) ("AIO operation complete: errorcode=%ld nbytes=%ld\n", dwErrorCode
, dwNumberOfBytesTransfered
);
54 int aio_read(struct aiocb
*aiocbp
)
56 LPOVERLAPPED Overlapped
;
57 BOOL IoOperationStatus
;
59 /* Allocate an overlapped structure. */
60 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
68 #if _FILE_OFFSET_BITS==64
70 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
72 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
76 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
78 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
83 Overlapped
->Offset
= aiocbp
->aio_offset
;
85 Overlapped
->OffsetHigh
= 0;
89 Overlapped
->hEvent
= aiocbp
;
91 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
93 aiocbp
->aio_sigevent
.sigev_signo
= -1;
95 IoOperationStatus
= ReadFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
101 /* Test to see if the I/O was queued successfully. */
102 if (!IoOperationStatus
)
104 errno
= GetLastError();
105 debug(81,1) ("aio_read: GetLastError=%i\n", errno
);
109 /* The I/O queued successfully. Go back into the
110 alertable wait for I/O completion or for
111 more I/O requests. */
116 int aio_read64(struct aiocb64
*aiocbp
)
118 LPOVERLAPPED Overlapped
;
119 BOOL IoOperationStatus
;
121 /* Allocate an overlapped structure. */
122 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
131 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
133 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
137 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
139 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
143 Overlapped
->hEvent
= aiocbp
;
145 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
147 aiocbp
->aio_sigevent
.sigev_signo
= -1;
149 IoOperationStatus
= ReadFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
153 IoCompletionRoutine
);
155 /* Test to see if the I/O was queued successfully. */
156 if (!IoOperationStatus
)
158 errno
= GetLastError();
159 debug(81,1) ("aio_read: GetLastError=%i\n", errno
);
163 /* The I/O queued successfully. Go back into the
164 alertable wait for I/O completion or for
165 more I/O requests. */
170 int aio_write(struct aiocb
*aiocbp
)
172 LPOVERLAPPED Overlapped
;
173 BOOL IoOperationStatus
;
175 /* Allocate an overlapped structure. */
176 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
184 #if _FILE_OFFSET_BITS==64
186 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
188 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
192 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
194 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
199 Overlapped
->Offset
= aiocbp
->aio_offset
;
201 Overlapped
->OffsetHigh
= 0;
205 Overlapped
->hEvent
= aiocbp
;
207 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
209 aiocbp
->aio_sigevent
.sigev_signo
= -1;
211 IoOperationStatus
= WriteFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
215 IoCompletionRoutine
);
217 /* Test to see if the I/O was queued successfully. */
218 if (!IoOperationStatus
)
220 errno
= GetLastError();
221 debug(81,1) ("aio_write: GetLastError=%i\n", errno
);
225 /* The I/O queued successfully. Go back into the
226 alertable wait for I/O completion or for
227 more I/O requests. */
232 int aio_write64(struct aiocb64
*aiocbp
)
234 LPOVERLAPPED Overlapped
;
235 BOOL IoOperationStatus
;
237 /* Allocate an overlapped structure. */
238 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
247 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
249 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
253 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
255 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
259 Overlapped
->hEvent
= aiocbp
;
261 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
263 aiocbp
->aio_sigevent
.sigev_signo
= -1;
265 IoOperationStatus
= WriteFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
269 IoCompletionRoutine
);
271 /* Test to see if the I/O was queued successfully. */
272 if (!IoOperationStatus
)
274 errno
= GetLastError();
275 debug(81,1) ("aio_write: GetLastError=%i\n", errno
);
279 /* The I/O queued successfully. Go back into the
280 alertable wait for I/O completion or for
281 more I/O requests. */
286 int aio_error(const struct aiocb
* aiocbp
)
288 return aiocbp
->aio_sigevent
.sigev_notify
;
292 int aio_error64(const struct aiocb64
* aiocbp
)
294 return aiocbp
->aio_sigevent
.sigev_notify
;
298 int aio_open(const char *path
, int mode
)
301 DWORD dwCreationDisposition
;
302 DWORD dwDesiredAccess
;
313 dwDesiredAccess
= GENERIC_WRITE
;
315 dwDesiredAccess
= (mode
& O_RDONLY
) ? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
;
318 dwCreationDisposition
= CREATE_ALWAYS
;
320 dwCreationDisposition
= (mode
& O_CREAT
) ? OPEN_ALWAYS
: OPEN_EXISTING
;
322 if ((hndl
= CreateFile(path
, /* file name */
323 dwDesiredAccess
, /* access mode */
326 dwCreationDisposition
, /* how to create */
327 FILE_FLAG_OVERLAPPED
, /* file attributes */
328 NULL
/* handle to template file */
329 )) != INVALID_HANDLE_VALUE
) {
330 statCounter
.syscalls
.disk
.opens
++;
331 fd
= _open_osfhandle((long) hndl
, 0);
332 commSetCloseOnExec(fd
);
333 fd_open(fd
, FD_FILE
, path
);
335 errno
= GetLastError();
343 void aio_close(int fd
)
345 CloseHandle((HANDLE
)_get_osfhandle(fd
));
347 statCounter
.syscalls
.disk
.closes
++;
351 ssize_t
aio_return(struct aiocb
* aiocbp
)
353 return aiocbp
->aio_sigevent
.sigev_signo
;
357 ssize_t
aio_return64(struct aiocb64
* aiocbp
)
360 return aiocbp
->aio_sigevent
.sigev_signo
;
362 #endif /* _SQUID_WIN32_ */