aio_win32.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9/* DEBUG: section 81 aio_xxx() POSIX emulation on Windows */
10
11#include "squid.h"
12#include "comm.h"
14#include "fd.h"
15#include "StatCounters.h"
16#include "win32.h"
17
18#include <cerrno>
19
20#if _SQUID_WINDOWS_
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;
29 debugs(81, 7, "AIO operation complete: errorcode=" << dwErrorCode << " nbytes=" << dwNumberOfBytesTransfered);
30 xfree(lpOverlapped);
31}
32
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
41 if (!Overlapped) {
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. */
80 if (!IoOperationStatus) {
81 errno = GetLastError();
82 debugs(81, DBG_IMPORTANT, "aio_read: GetLastError=" << errno );
83 return -1;
84 }
85
86 /* The I/O queued successfully. Go back into the
87 alertable wait for I/O completion or for
88 more I/O requests. */
89 return 0;
90}
91
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
100 if (!Overlapped) {
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. */
131 if (!IoOperationStatus) {
132 errno = GetLastError();
133 debugs(81, DBG_IMPORTANT, "aio_read: GetLastError=" << errno );
134 return -1;
135 }
136
137 /* The I/O queued successfully. Go back into the
138 alertable wait for I/O completion or for
139 more I/O requests. */
140 return 0;
141}
142
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
151 if (!Overlapped) {
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. */
190 if (!IoOperationStatus) {
191 errno = GetLastError();
192 debugs(81, DBG_IMPORTANT, "aio_write: GetLastError=" << errno );
193 return -1;
194 }
195
196 /* The I/O queued successfully. Go back into the
197 alertable wait for I/O completion or for
198 more I/O requests. */
199 return 0;
200}
201
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
210 if (!Overlapped) {
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. */
241 if (!IoOperationStatus) {
242 errno = GetLastError();
243 debugs(81, DBG_IMPORTANT, "aio_write: GetLastError=" << errno );
244 return -1;
245 }
246
247 /* The I/O queued successfully. Go back into the
248 alertable wait for I/O completion or for
249 more I/O requests. */
250 return 0;
251}
252
253int aio_error(const struct aiocb * aiocbp)
254{
255 return aiocbp->aio_sigevent.sigev_notify;
256}
257
258int aio_error64(const struct aiocb64 * aiocbp)
259{
260 return aiocbp->aio_sigevent.sigev_notify;
261}
262
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
287 if ((hndl = CreateFile(path, /* file name */
288 dwDesiredAccess, /* access mode */
289 0, /* share mode */
290 nullptr, /* SD */
291 dwCreationDisposition, /* how to create */
292 FILE_FLAG_OVERLAPPED, /* file attributes */
293 NULL /* handle to template file */
294 )) != INVALID_HANDLE_VALUE) {
296 fd = _open_osfhandle((long) hndl, 0);
298 fd_open(fd, FD_FILE, path);
299 } else {
300 errno = GetLastError();
301 fd = DISK_ERROR;
302 }
303
304 return fd;
305}
306
307void aio_close(int fd)
308{
309 CloseHandle((HANDLE)_get_osfhandle(fd));
310 fd_close(fd);
312}
313
314ssize_t aio_return(struct aiocb * aiocbp)
315{
316 return aiocbp->aio_sigevent.sigev_signo;
317}
318
319ssize_t aio_return64(struct aiocb64 * aiocbp)
320
321{
322 return aiocbp->aio_sigevent.sigev_signo;
323}
324#endif /* _SQUID_WINDOWS_ */
325
StatCounters statCounter
Definition: StatCounters.cc:12
struct StatCounters::@130 syscalls
struct StatCounters::@130::@134 disk
void fd_open(const int fd, unsigned int, const char *description)
Definition: minimal.cc:14
void fd_close(const int fd)
Definition: minimal.cc:20
void commSetCloseOnExec(int fd)
Definition: comm.cc:1127
#define DBG_IMPORTANT
Definition: Stream.h:38
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:194
#define O_BINARY
Definition: defines.h:136
#define DISK_ERROR
Definition: defines.h:28
@ FD_FILE
Definition: enums.h:15
#define xfree
#define BOOL
Definition: std-includes.h:38
#define NULL
Definition: types.h:145
void * xcalloc(size_t n, size_t sz)
Definition: xalloc.cc:71

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors