3 * DEBUG: section 81 aio_xxx() POSIX emulation on Windows
4 * AUTHOR: Guido Serassio <serassio@squid-cache.org>
6 * SQUID Web Proxy Cache http://www.squid-cache.org/
7 * ----------------------------------------------------------
9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
35 #include "DiskIO/AIO/aio_win32.h"
38 #include "StatCounters.h"
46 VOID CALLBACK
IoCompletionRoutine(DWORD dwErrorCode
,
47 DWORD dwNumberOfBytesTransfered
, LPOVERLAPPED lpOverlapped
)
50 struct aiocb
*aiocbp
= (struct aiocb
*) lpOverlapped
->hEvent
;
52 aiocbp
->aio_sigevent
.sigev_notify
= dwErrorCode
;
53 aiocbp
->aio_sigevent
.sigev_signo
= dwNumberOfBytesTransfered
;
54 debugs(81, 7, "AIO operation complete: errorcode=" << dwErrorCode
<< " nbytes=" << dwNumberOfBytesTransfered
);
58 int aio_read(struct aiocb
*aiocbp
)
60 LPOVERLAPPED Overlapped
;
61 BOOL IoOperationStatus
;
63 /* Allocate an overlapped structure. */
64 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
71 #if _FILE_OFFSET_BITS==64
73 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
75 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
79 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
81 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
86 Overlapped
->Offset
= aiocbp
->aio_offset
;
88 Overlapped
->OffsetHigh
= 0;
92 Overlapped
->hEvent
= aiocbp
;
94 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
96 aiocbp
->aio_sigevent
.sigev_signo
= -1;
98 IoOperationStatus
= ReadFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
102 IoCompletionRoutine
);
104 /* Test to see if the I/O was queued successfully. */
105 if (!IoOperationStatus
) {
106 errno
= GetLastError();
107 debugs(81, DBG_IMPORTANT
, "aio_read: GetLastError=" << errno
);
111 /* The I/O queued successfully. Go back into the
112 alertable wait for I/O completion or for
113 more I/O requests. */
117 int aio_read64(struct aiocb64
*aiocbp
)
119 LPOVERLAPPED Overlapped
;
120 BOOL IoOperationStatus
;
122 /* Allocate an overlapped structure. */
123 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
) {
157 errno
= GetLastError();
158 debugs(81, DBG_IMPORTANT
, "aio_read: GetLastError=" << errno
);
162 /* The I/O queued successfully. Go back into the
163 alertable wait for I/O completion or for
164 more I/O requests. */
168 int aio_write(struct aiocb
*aiocbp
)
170 LPOVERLAPPED Overlapped
;
171 BOOL IoOperationStatus
;
173 /* Allocate an overlapped structure. */
174 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
181 #if _FILE_OFFSET_BITS==64
183 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
185 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
189 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
191 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
196 Overlapped
->Offset
= aiocbp
->aio_offset
;
198 Overlapped
->OffsetHigh
= 0;
202 Overlapped
->hEvent
= aiocbp
;
204 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
206 aiocbp
->aio_sigevent
.sigev_signo
= -1;
208 IoOperationStatus
= WriteFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
212 IoCompletionRoutine
);
214 /* Test to see if the I/O was queued successfully. */
215 if (!IoOperationStatus
) {
216 errno
= GetLastError();
217 debugs(81, DBG_IMPORTANT
, "aio_write: GetLastError=" << errno
);
221 /* The I/O queued successfully. Go back into the
222 alertable wait for I/O completion or for
223 more I/O requests. */
227 int aio_write64(struct aiocb64
*aiocbp
)
229 LPOVERLAPPED Overlapped
;
230 BOOL IoOperationStatus
;
232 /* Allocate an overlapped structure. */
233 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
241 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
243 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
247 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
249 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
253 Overlapped
->hEvent
= aiocbp
;
255 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
257 aiocbp
->aio_sigevent
.sigev_signo
= -1;
259 IoOperationStatus
= WriteFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
263 IoCompletionRoutine
);
265 /* Test to see if the I/O was queued successfully. */
266 if (!IoOperationStatus
) {
267 errno
= GetLastError();
268 debugs(81, DBG_IMPORTANT
, "aio_write: GetLastError=" << errno
);
272 /* The I/O queued successfully. Go back into the
273 alertable wait for I/O completion or for
274 more I/O requests. */
278 int aio_error(const struct aiocb
* aiocbp
)
280 return aiocbp
->aio_sigevent
.sigev_notify
;
283 int aio_error64(const struct aiocb64
* aiocbp
)
285 return aiocbp
->aio_sigevent
.sigev_notify
;
288 int aio_open(const char *path
, int mode
)
291 DWORD dwCreationDisposition
;
292 DWORD dwDesiredAccess
;
303 dwDesiredAccess
= GENERIC_WRITE
;
305 dwDesiredAccess
= (mode
& O_RDONLY
) ? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
;
308 dwCreationDisposition
= CREATE_ALWAYS
;
310 dwCreationDisposition
= (mode
& O_CREAT
) ? OPEN_ALWAYS
: OPEN_EXISTING
;
312 if ((hndl
= CreateFile(path
, /* file name */
313 dwDesiredAccess
, /* access mode */
316 dwCreationDisposition
, /* how to create */
317 FILE_FLAG_OVERLAPPED
, /* file attributes */
318 NULL
/* handle to template file */
319 )) != INVALID_HANDLE_VALUE
) {
320 ++ statCounter
.syscalls
.disk
.opens
;
321 fd
= _open_osfhandle((long) hndl
, 0);
322 commSetCloseOnExec(fd
);
323 fd_open(fd
, FD_FILE
, path
);
325 errno
= GetLastError();
332 void aio_close(int fd
)
334 CloseHandle((HANDLE
)_get_osfhandle(fd
));
336 ++ statCounter
.syscalls
.disk
.closes
;
339 ssize_t
aio_return(struct aiocb
* aiocbp
)
341 return aiocbp
->aio_sigevent
.sigev_signo
;
344 ssize_t
aio_return64(struct aiocb64
* aiocbp
)
347 return aiocbp
->aio_sigevent
.sigev_signo
;
349 #endif /* _SQUID_WINDOWS_ */