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.
36 #include "aio_win32.h"
43 VOID CALLBACK
IoCompletionRoutine(DWORD dwErrorCode
,
44 DWORD dwNumberOfBytesTransfered
, LPOVERLAPPED lpOverlapped
)
47 struct aiocb
*aiocbp
= (struct aiocb
*) lpOverlapped
->hEvent
;
49 aiocbp
->aio_sigevent
.sigev_notify
= dwErrorCode
;
50 aiocbp
->aio_sigevent
.sigev_signo
= dwNumberOfBytesTransfered
;
51 debugs(81, 7, "AIO operation complete: errorcode=" << dwErrorCode
<< " nbytes=" << dwNumberOfBytesTransfered
);
55 int aio_read(struct aiocb
*aiocbp
)
57 LPOVERLAPPED Overlapped
;
58 BOOL IoOperationStatus
;
60 /* Allocate an overlapped structure. */
61 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
) {
103 errno
= GetLastError();
104 debugs(81, DBG_IMPORTANT
, "aio_read: GetLastError=" << errno
);
108 /* The I/O queued successfully. Go back into the
109 alertable wait for I/O completion or for
110 more I/O requests. */
114 int aio_read64(struct aiocb64
*aiocbp
)
116 LPOVERLAPPED Overlapped
;
117 BOOL IoOperationStatus
;
119 /* Allocate an overlapped structure. */
120 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
128 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
130 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
134 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
136 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
140 Overlapped
->hEvent
= aiocbp
;
142 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
144 aiocbp
->aio_sigevent
.sigev_signo
= -1;
146 IoOperationStatus
= ReadFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
150 IoCompletionRoutine
);
152 /* Test to see if the I/O was queued successfully. */
153 if (!IoOperationStatus
) {
154 errno
= GetLastError();
155 debugs(81, DBG_IMPORTANT
, "aio_read: GetLastError=" << errno
);
159 /* The I/O queued successfully. Go back into the
160 alertable wait for I/O completion or for
161 more I/O requests. */
165 int aio_write(struct aiocb
*aiocbp
)
167 LPOVERLAPPED Overlapped
;
168 BOOL IoOperationStatus
;
170 /* Allocate an overlapped structure. */
171 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
178 #if _FILE_OFFSET_BITS==64
180 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
182 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
186 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
188 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
193 Overlapped
->Offset
= aiocbp
->aio_offset
;
195 Overlapped
->OffsetHigh
= 0;
199 Overlapped
->hEvent
= aiocbp
;
201 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
203 aiocbp
->aio_sigevent
.sigev_signo
= -1;
205 IoOperationStatus
= WriteFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
209 IoCompletionRoutine
);
211 /* Test to see if the I/O was queued successfully. */
212 if (!IoOperationStatus
) {
213 errno
= GetLastError();
214 debugs(81, DBG_IMPORTANT
, "aio_write: GetLastError=" << errno
);
218 /* The I/O queued successfully. Go back into the
219 alertable wait for I/O completion or for
220 more I/O requests. */
224 int aio_write64(struct aiocb64
*aiocbp
)
226 LPOVERLAPPED Overlapped
;
227 BOOL IoOperationStatus
;
229 /* Allocate an overlapped structure. */
230 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
238 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
240 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
244 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
246 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
250 Overlapped
->hEvent
= aiocbp
;
252 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
254 aiocbp
->aio_sigevent
.sigev_signo
= -1;
256 IoOperationStatus
= WriteFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
260 IoCompletionRoutine
);
262 /* Test to see if the I/O was queued successfully. */
263 if (!IoOperationStatus
) {
264 errno
= GetLastError();
265 debugs(81, DBG_IMPORTANT
, "aio_write: GetLastError=" << errno
);
269 /* The I/O queued successfully. Go back into the
270 alertable wait for I/O completion or for
271 more I/O requests. */
275 int aio_error(const struct aiocb
* aiocbp
)
277 return aiocbp
->aio_sigevent
.sigev_notify
;
280 int aio_error64(const struct aiocb64
* aiocbp
)
282 return aiocbp
->aio_sigevent
.sigev_notify
;
285 int aio_open(const char *path
, int mode
)
288 DWORD dwCreationDisposition
;
289 DWORD dwDesiredAccess
;
300 dwDesiredAccess
= GENERIC_WRITE
;
302 dwDesiredAccess
= (mode
& O_RDONLY
) ? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
;
305 dwCreationDisposition
= CREATE_ALWAYS
;
307 dwCreationDisposition
= (mode
& O_CREAT
) ? OPEN_ALWAYS
: OPEN_EXISTING
;
309 if ((hndl
= CreateFile(path
, /* file name */
310 dwDesiredAccess
, /* access mode */
313 dwCreationDisposition
, /* how to create */
314 FILE_FLAG_OVERLAPPED
, /* file attributes */
315 NULL
/* handle to template file */
316 )) != INVALID_HANDLE_VALUE
) {
317 ++ statCounter
.syscalls
.disk
.opens
;
318 fd
= _open_osfhandle((long) hndl
, 0);
319 commSetCloseOnExec(fd
);
320 fd_open(fd
, FD_FILE
, path
);
322 errno
= GetLastError();
329 void aio_close(int fd
)
331 CloseHandle((HANDLE
)_get_osfhandle(fd
));
333 ++ statCounter
.syscalls
.disk
.closes
;
336 ssize_t
aio_return(struct aiocb
* aiocbp
)
338 return aiocbp
->aio_sigevent
.sigev_signo
;
341 ssize_t
aio_return64(struct aiocb64
* aiocbp
)
344 return aiocbp
->aio_sigevent
.sigev_signo
;
346 #endif /* _SQUID_WINDOWS_ */