]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DiskIO/AIO/aio_win32.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / DiskIO / AIO / aio_win32.cc
CommitLineData
abb2a3d9 1/*
4ac4a490 2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
abb2a3d9 3 *
bbc27441
AJ
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.
abb2a3d9 7 */
8
bbc27441
AJ
9/* DEBUG: section 81 aio_xxx() POSIX emulation on Windows */
10
582c2af2 11#include "squid.h"
abb2a3d9 12#include "comm.h"
602d9612 13#include "DiskIO/AIO/aio_win32.h"
1e1a9021
AJ
14#include "fd.h"
15#include "StatCounters.h"
16#include "win32.h"
abb2a3d9 17
1a30fdf5 18#include <cerrno>
21d845b1 19
be266cb2 20#if _SQUID_WINDOWS_
abb2a3d9 21VOID CALLBACK IoCompletionRoutine(DWORD dwErrorCode,
22 DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
23{
24
25 struct aiocb *aiocbp = (struct aiocb *) lpOverlapped->hEvent;
26
27 aiocbp->aio_sigevent.sigev_notify = dwErrorCode;
28 aiocbp->aio_sigevent.sigev_signo = dwNumberOfBytesTransfered;
bf8fe701 29 debugs(81, 7, "AIO operation complete: errorcode=" << dwErrorCode << " nbytes=" << dwNumberOfBytesTransfered);
abb2a3d9 30 xfree(lpOverlapped);
31}
32
abb2a3d9 33int aio_read(struct aiocb *aiocbp)
34{
35 LPOVERLAPPED Overlapped;
36 BOOL IoOperationStatus;
37
38 /* Allocate an overlapped structure. */
39 Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED));
40
26ac0430 41 if (!Overlapped) {
abb2a3d9 42 errno = ENOMEM;
43 return -1;
44 }
45
46#if _FILE_OFFSET_BITS==64
47#ifdef __GNUC__
48 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
49
50 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
51
52#else
53
54 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
55
56 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
57
58#endif
59#else
60
61 Overlapped->Offset = aiocbp->aio_offset;
62
63 Overlapped->OffsetHigh = 0;
64
65#endif
66
67 Overlapped->hEvent = aiocbp;
68
69 aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
70
71 aiocbp->aio_sigevent.sigev_signo = -1;
72
73 IoOperationStatus = ReadFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
74 aiocbp->aio_buf,
75 aiocbp->aio_nbytes,
76 Overlapped,
77 IoCompletionRoutine);
78
79 /* Test to see if the I/O was queued successfully. */
26ac0430 80 if (!IoOperationStatus) {
abb2a3d9 81 errno = GetLastError();
e0236918 82 debugs(81, DBG_IMPORTANT, "aio_read: GetLastError=" << errno );
abb2a3d9 83 return -1;
84 }
85
86 /* The I/O queued successfully. Go back into the
26ac0430 87 alertable wait for I/O completion or for
abb2a3d9 88 more I/O requests. */
89 return 0;
90}
91
abb2a3d9 92int aio_read64(struct aiocb64 *aiocbp)
93{
94 LPOVERLAPPED Overlapped;
95 BOOL IoOperationStatus;
96
97 /* Allocate an overlapped structure. */
98 Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED));
99
26ac0430 100 if (!Overlapped) {
abb2a3d9 101 errno = ENOMEM;
102 return -1;
103 }
104
105#ifdef __GNUC__
106 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
107
108 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
109
110#else
111
112 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
113
114 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
115
116#endif
117
118 Overlapped->hEvent = aiocbp;
119
120 aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
121
122 aiocbp->aio_sigevent.sigev_signo = -1;
123
124 IoOperationStatus = ReadFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
125 aiocbp->aio_buf,
126 aiocbp->aio_nbytes,
127 Overlapped,
128 IoCompletionRoutine);
129
130 /* Test to see if the I/O was queued successfully. */
26ac0430 131 if (!IoOperationStatus) {
abb2a3d9 132 errno = GetLastError();
e0236918 133 debugs(81, DBG_IMPORTANT, "aio_read: GetLastError=" << errno );
abb2a3d9 134 return -1;
135 }
136
137 /* The I/O queued successfully. Go back into the
26ac0430 138 alertable wait for I/O completion or for
abb2a3d9 139 more I/O requests. */
140 return 0;
141}
142
abb2a3d9 143int aio_write(struct aiocb *aiocbp)
144{
145 LPOVERLAPPED Overlapped;
146 BOOL IoOperationStatus;
147
148 /* Allocate an overlapped structure. */
149 Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED));
150
26ac0430 151 if (!Overlapped) {
abb2a3d9 152 errno = ENOMEM;
153 return -1;
154 }
155
156#if _FILE_OFFSET_BITS==64
157#ifdef __GNUC__
158 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
159
160 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
161
162#else
163
164 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
165
166 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
167
168#endif
169#else
170
171 Overlapped->Offset = aiocbp->aio_offset;
172
173 Overlapped->OffsetHigh = 0;
174
175#endif
176
177 Overlapped->hEvent = aiocbp;
178
179 aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
180
181 aiocbp->aio_sigevent.sigev_signo = -1;
182
183 IoOperationStatus = WriteFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
184 aiocbp->aio_buf,
185 aiocbp->aio_nbytes,
186 Overlapped,
187 IoCompletionRoutine);
188
189 /* Test to see if the I/O was queued successfully. */
26ac0430 190 if (!IoOperationStatus) {
abb2a3d9 191 errno = GetLastError();
e0236918 192 debugs(81, DBG_IMPORTANT, "aio_write: GetLastError=" << errno );
abb2a3d9 193 return -1;
194 }
195
196 /* The I/O queued successfully. Go back into the
26ac0430 197 alertable wait for I/O completion or for
abb2a3d9 198 more I/O requests. */
199 return 0;
200}
201
abb2a3d9 202int aio_write64(struct aiocb64 *aiocbp)
203{
204 LPOVERLAPPED Overlapped;
205 BOOL IoOperationStatus;
206
207 /* Allocate an overlapped structure. */
208 Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED));
209
26ac0430 210 if (!Overlapped) {
abb2a3d9 211 errno = ENOMEM;
212 return -1;
213 }
214
215#ifdef __GNUC__
216 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
217
218 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
219
220#else
221
222 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
223
224 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
225
226#endif
227
228 Overlapped->hEvent = aiocbp;
229
230 aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
231
232 aiocbp->aio_sigevent.sigev_signo = -1;
233
234 IoOperationStatus = WriteFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
235 aiocbp->aio_buf,
236 aiocbp->aio_nbytes,
237 Overlapped,
238 IoCompletionRoutine);
239
240 /* Test to see if the I/O was queued successfully. */
26ac0430 241 if (!IoOperationStatus) {
abb2a3d9 242 errno = GetLastError();
e0236918 243 debugs(81, DBG_IMPORTANT, "aio_write: GetLastError=" << errno );
abb2a3d9 244 return -1;
245 }
246
247 /* The I/O queued successfully. Go back into the
26ac0430 248 alertable wait for I/O completion or for
abb2a3d9 249 more I/O requests. */
250 return 0;
251}
252
abb2a3d9 253int aio_error(const struct aiocb * aiocbp)
254{
255 return aiocbp->aio_sigevent.sigev_notify;
256}
257
abb2a3d9 258int aio_error64(const struct aiocb64 * aiocbp)
259{
260 return aiocbp->aio_sigevent.sigev_notify;
261}
262
abb2a3d9 263int aio_open(const char *path, int mode)
264{
265 HANDLE hndl;
266 DWORD dwCreationDisposition;
267 DWORD dwDesiredAccess;
268 int fd;
269
270 if (mode & O_WRONLY)
271 mode |= O_APPEND;
272
273 mode |= O_BINARY;
274
275 errno = 0;
276
277 if (mode & O_WRONLY)
278 dwDesiredAccess = GENERIC_WRITE;
279 else
280 dwDesiredAccess = (mode & O_RDONLY) ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE;
281
282 if (mode & O_TRUNC)
283 dwCreationDisposition = CREATE_ALWAYS;
284 else
285 dwCreationDisposition = (mode & O_CREAT) ? OPEN_ALWAYS : OPEN_EXISTING;
286
f53969cc
SM
287 if ((hndl = CreateFile(path, /* file name */
288 dwDesiredAccess, /* access mode */
289 0, /* share mode */
290 NULL, /* SD */
291 dwCreationDisposition, /* how to create */
292 FILE_FLAG_OVERLAPPED, /* file attributes */
293 NULL /* handle to template file */
abb2a3d9 294 )) != INVALID_HANDLE_VALUE) {
cb4185f1 295 ++ statCounter.syscalls.disk.opens;
abb2a3d9 296 fd = _open_osfhandle((long) hndl, 0);
297 commSetCloseOnExec(fd);
298 fd_open(fd, FD_FILE, path);
299 } else {
300 errno = GetLastError();
301 fd = DISK_ERROR;
302 }
303
304 return fd;
305}
306
abb2a3d9 307void aio_close(int fd)
308{
309 CloseHandle((HANDLE)_get_osfhandle(fd));
310 fd_close(fd);
cb4185f1 311 ++ statCounter.syscalls.disk.closes;
abb2a3d9 312}
313
abb2a3d9 314ssize_t aio_return(struct aiocb * aiocbp)
315{
316 return aiocbp->aio_sigevent.sigev_signo;
317}
318
abb2a3d9 319ssize_t aio_return64(struct aiocb64 * aiocbp)
320
321{
322 return aiocbp->aio_sigevent.sigev_signo;
323}
be266cb2 324#endif /* _SQUID_WINDOWS_ */
f53969cc 325