2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 81 aio_xxx() POSIX emulation on Windows */
13 #include "DiskIO/AIO/aio_win32.h"
15 #include "StatCounters.h"
21 VOID CALLBACK
IoCompletionRoutine(DWORD dwErrorCode
,
22 DWORD dwNumberOfBytesTransfered
, LPOVERLAPPED lpOverlapped
)
25 struct aiocb
*aiocbp
= (struct aiocb
*) lpOverlapped
->hEvent
;
27 aiocbp
->aio_sigevent
.sigev_notify
= dwErrorCode
;
28 aiocbp
->aio_sigevent
.sigev_signo
= dwNumberOfBytesTransfered
;
29 debugs(81, 7, "AIO operation complete: errorcode=" << dwErrorCode
<< " nbytes=" << dwNumberOfBytesTransfered
);
33 int aio_read(struct aiocb
*aiocbp
)
35 LPOVERLAPPED Overlapped
;
36 BOOL IoOperationStatus
;
38 /* Allocate an overlapped structure. */
39 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
46 #if _FILE_OFFSET_BITS==64
48 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
50 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
54 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
56 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
61 Overlapped
->Offset
= aiocbp
->aio_offset
;
63 Overlapped
->OffsetHigh
= 0;
67 Overlapped
->hEvent
= aiocbp
;
69 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
71 aiocbp
->aio_sigevent
.sigev_signo
= -1;
73 IoOperationStatus
= ReadFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
79 /* Test to see if the I/O was queued successfully. */
80 if (!IoOperationStatus
) {
81 errno
= GetLastError();
82 debugs(81, DBG_IMPORTANT
, "aio_read: GetLastError=" << errno
);
86 /* The I/O queued successfully. Go back into the
87 alertable wait for I/O completion or for
92 int aio_read64(struct aiocb64
*aiocbp
)
94 LPOVERLAPPED Overlapped
;
95 BOOL IoOperationStatus
;
97 /* Allocate an overlapped structure. */
98 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
106 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
108 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
112 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
114 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
118 Overlapped
->hEvent
= aiocbp
;
120 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
122 aiocbp
->aio_sigevent
.sigev_signo
= -1;
124 IoOperationStatus
= ReadFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
128 IoCompletionRoutine
);
130 /* Test to see if the I/O was queued successfully. */
131 if (!IoOperationStatus
) {
132 errno
= GetLastError();
133 debugs(81, DBG_IMPORTANT
, "aio_read: GetLastError=" << errno
);
137 /* The I/O queued successfully. Go back into the
138 alertable wait for I/O completion or for
139 more I/O requests. */
143 int aio_write(struct aiocb
*aiocbp
)
145 LPOVERLAPPED Overlapped
;
146 BOOL IoOperationStatus
;
148 /* Allocate an overlapped structure. */
149 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
156 #if _FILE_OFFSET_BITS==64
158 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
160 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
164 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
166 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
171 Overlapped
->Offset
= aiocbp
->aio_offset
;
173 Overlapped
->OffsetHigh
= 0;
177 Overlapped
->hEvent
= aiocbp
;
179 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
181 aiocbp
->aio_sigevent
.sigev_signo
= -1;
183 IoOperationStatus
= WriteFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
187 IoCompletionRoutine
);
189 /* Test to see if the I/O was queued successfully. */
190 if (!IoOperationStatus
) {
191 errno
= GetLastError();
192 debugs(81, DBG_IMPORTANT
, "aio_write: GetLastError=" << errno
);
196 /* The I/O queued successfully. Go back into the
197 alertable wait for I/O completion or for
198 more I/O requests. */
202 int aio_write64(struct aiocb64
*aiocbp
)
204 LPOVERLAPPED Overlapped
;
205 BOOL IoOperationStatus
;
207 /* Allocate an overlapped structure. */
208 Overlapped
= (LPOVERLAPPED
) xcalloc(1, sizeof(OVERLAPPED
));
216 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000LL
);
218 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000LL
);
222 Overlapped
->Offset
= (DWORD
) (aiocbp
->aio_offset
% 0x100000000);
224 Overlapped
->OffsetHigh
= (DWORD
) (aiocbp
->aio_offset
/ 0x100000000);
228 Overlapped
->hEvent
= aiocbp
;
230 aiocbp
->aio_sigevent
.sigev_notify
= EINPROGRESS
;
232 aiocbp
->aio_sigevent
.sigev_signo
= -1;
234 IoOperationStatus
= WriteFileEx((HANDLE
)_get_osfhandle(aiocbp
->aio_fildes
),
238 IoCompletionRoutine
);
240 /* Test to see if the I/O was queued successfully. */
241 if (!IoOperationStatus
) {
242 errno
= GetLastError();
243 debugs(81, DBG_IMPORTANT
, "aio_write: GetLastError=" << errno
);
247 /* The I/O queued successfully. Go back into the
248 alertable wait for I/O completion or for
249 more I/O requests. */
253 int aio_error(const struct aiocb
* aiocbp
)
255 return aiocbp
->aio_sigevent
.sigev_notify
;
258 int aio_error64(const struct aiocb64
* aiocbp
)
260 return aiocbp
->aio_sigevent
.sigev_notify
;
263 int aio_open(const char *path
, int mode
)
266 DWORD dwCreationDisposition
;
267 DWORD dwDesiredAccess
;
278 dwDesiredAccess
= GENERIC_WRITE
;
280 dwDesiredAccess
= (mode
& O_RDONLY
) ? GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
;
283 dwCreationDisposition
= CREATE_ALWAYS
;
285 dwCreationDisposition
= (mode
& O_CREAT
) ? OPEN_ALWAYS
: OPEN_EXISTING
;
287 if ((hndl
= CreateFile(path
, /* file name */
288 dwDesiredAccess
, /* access mode */
291 dwCreationDisposition
, /* how to create */
292 FILE_FLAG_OVERLAPPED
, /* file attributes */
293 NULL
/* handle to template file */
294 )) != INVALID_HANDLE_VALUE
) {
295 ++ statCounter
.syscalls
.disk
.opens
;
296 fd
= _open_osfhandle((long) hndl
, 0);
297 commSetCloseOnExec(fd
);
298 fd_open(fd
, FD_FILE
, path
);
300 errno
= GetLastError();
307 void aio_close(int fd
)
309 CloseHandle((HANDLE
)_get_osfhandle(fd
));
311 ++ statCounter
.syscalls
.disk
.closes
;
314 ssize_t
aio_return(struct aiocb
* aiocbp
)
316 return aiocbp
->aio_sigevent
.sigev_signo
;
319 ssize_t
aio_return64(struct aiocb64
* aiocbp
)
322 return aiocbp
->aio_sigevent
.sigev_signo
;
324 #endif /* _SQUID_WINDOWS_ */