5 * DEBUG: section 81 aio_xxx() POSIX emulation on Windows
6 * AUTHOR: Guido Serassio <serassio@squid-cache.org>
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 debugs(81, 7, "AIO operation complete: errorcode=" << dwErrorCode
<< " nbytes=" << 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
));
67 #if _FILE_OFFSET_BITS==64
69 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
71 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
75 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
77 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
82 Overlapped
->Offset
= aiocbp
->aio_offset
;
84 Overlapped
->OffsetHigh
= 0;
88 Overlapped
->hEvent
= aiocbp
;
90 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
92 aiocbp
->aio_sigevent
.sigev_signo
= -1;
94 IoOperationStatus
= ReadFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
100 /* Test to see if the I/O was queued successfully. */
101 if (!IoOperationStatus
) {
102 errno
= GetLastError();
103 debugs(81,1, "aio_read: GetLastError=" << errno
);
107 /* The I/O queued successfully. Go back into the
108 alertable wait for I/O completion or for
109 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, 1, "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. */
166 int aio_write(struct aiocb
*aiocbp
)
168 LPOVERLAPPED Overlapped
;
169 BOOL IoOperationStatus
;
171 /* Allocate an overlapped structure. */
172 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
179 #if _FILE_OFFSET_BITS==64
181 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
183 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
187 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
189 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
194 Overlapped
->Offset
= aiocbp
->aio_offset
;
196 Overlapped
->OffsetHigh
= 0;
200 Overlapped
->hEvent
= aiocbp
;
202 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
204 aiocbp
->aio_sigevent
.sigev_signo
= -1;
206 IoOperationStatus
= WriteFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
210 IoCompletionRoutine
);
212 /* Test to see if the I/O was queued successfully. */
213 if (!IoOperationStatus
) {
214 errno
= GetLastError();
215 debugs(81, 1, "aio_write: GetLastError=" << errno
);
219 /* The I/O queued successfully. Go back into the
220 alertable wait for I/O completion or for
221 more I/O requests. */
226 int aio_write64(struct aiocb64
*aiocbp
)
228 LPOVERLAPPED Overlapped
;
229 BOOL IoOperationStatus
;
231 /* Allocate an overlapped structure. */
232 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
240 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
242 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
246 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
248 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
252 Overlapped
->hEvent
= aiocbp
;
254 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
256 aiocbp
->aio_sigevent
.sigev_signo
= -1;
258 IoOperationStatus
= WriteFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
262 IoCompletionRoutine
);
264 /* Test to see if the I/O was queued successfully. */
265 if (!IoOperationStatus
) {
266 errno
= GetLastError();
267 debugs(81, 1, "aio_write: GetLastError=" << errno
);
271 /* The I/O queued successfully. Go back into the
272 alertable wait for I/O completion or for
273 more I/O requests. */
278 int aio_error(const struct aiocb
* aiocbp
)
280 return aiocbp
->aio_sigevent
.sigev_notify
;
284 int aio_error64(const struct aiocb64
* aiocbp
)
286 return aiocbp
->aio_sigevent
.sigev_notify
;
290 int aio_open(const char *path
, int mode
)
293 DWORD dwCreationDisposition
;
294 DWORD dwDesiredAccess
;
305 dwDesiredAccess
= GENERIC_WRITE
;
307 dwDesiredAccess
= (mode
& O_RDONLY
) ? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
;
310 dwCreationDisposition
= CREATE_ALWAYS
;
312 dwCreationDisposition
= (mode
& O_CREAT
) ? OPEN_ALWAYS
: OPEN_EXISTING
;
314 if ((hndl
= CreateFile(path
, /* file name */
315 dwDesiredAccess
, /* access mode */
318 dwCreationDisposition
, /* how to create */
319 FILE_FLAG_OVERLAPPED
, /* file attributes */
320 NULL
/* handle to template file */
321 )) != INVALID_HANDLE_VALUE
) {
322 statCounter
.syscalls
.disk
.opens
++;
323 fd
= _open_osfhandle((long) hndl
, 0);
324 commSetCloseOnExec(fd
);
325 fd_open(fd
, FD_FILE
, path
);
327 errno
= GetLastError();
335 void aio_close(int fd
)
337 CloseHandle((HANDLE
)_get_osfhandle(fd
));
339 statCounter
.syscalls
.disk
.closes
++;
343 ssize_t
aio_return(struct aiocb
* aiocbp
)
345 return aiocbp
->aio_sigevent
.sigev_signo
;
349 ssize_t
aio_return64(struct aiocb64
* aiocbp
)
352 return aiocbp
->aio_sigevent
.sigev_signo
;
354 #endif /* _SQUID_WIN32_ */