]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/AIO/aio_win32.cc
Removed CVS $ markers
[thirdparty/squid.git] / src / DiskIO / AIO / aio_win32.cc
1
2 /*
3 * DEBUG: section 81 aio_xxx() POSIX emulation on Windows
4 * AUTHOR: Guido Serassio <serassio@squid-cache.org>
5 *
6 * SQUID Web Proxy Cache http://www.squid-cache.org/
7 * ----------------------------------------------------------
8 *
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.
17 *
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.
22 *
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.
27 *
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.
31 *
32 */
33
34 #include "squid.h"
35 #include "comm.h"
36 #include "aio_win32.h"
37
38 #if HAVE_ERRNO_H
39 #include <errno.h>
40 #endif
41
42 #if _SQUID_WINDOWS_
43 VOID CALLBACK IoCompletionRoutine(DWORD dwErrorCode,
44 DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
45 {
46
47 struct aiocb *aiocbp = (struct aiocb *) lpOverlapped->hEvent;
48
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);
52 xfree(lpOverlapped);
53 }
54
55 int aio_read(struct aiocb *aiocbp)
56 {
57 LPOVERLAPPED Overlapped;
58 BOOL IoOperationStatus;
59
60 /* Allocate an overlapped structure. */
61 Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED));
62
63 if (!Overlapped) {
64 errno = ENOMEM;
65 return -1;
66 }
67
68 #if _FILE_OFFSET_BITS==64
69 #ifdef __GNUC__
70 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
71
72 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
73
74 #else
75
76 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
77
78 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
79
80 #endif
81 #else
82
83 Overlapped->Offset = aiocbp->aio_offset;
84
85 Overlapped->OffsetHigh = 0;
86
87 #endif
88
89 Overlapped->hEvent = aiocbp;
90
91 aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
92
93 aiocbp->aio_sigevent.sigev_signo = -1;
94
95 IoOperationStatus = ReadFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
96 aiocbp->aio_buf,
97 aiocbp->aio_nbytes,
98 Overlapped,
99 IoCompletionRoutine);
100
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 );
105 return -1;
106 }
107
108 /* The I/O queued successfully. Go back into the
109 alertable wait for I/O completion or for
110 more I/O requests. */
111 return 0;
112 }
113
114 int aio_read64(struct aiocb64 *aiocbp)
115 {
116 LPOVERLAPPED Overlapped;
117 BOOL IoOperationStatus;
118
119 /* Allocate an overlapped structure. */
120 Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED));
121
122 if (!Overlapped) {
123 errno = ENOMEM;
124 return -1;
125 }
126
127 #ifdef __GNUC__
128 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
129
130 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
131
132 #else
133
134 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
135
136 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
137
138 #endif
139
140 Overlapped->hEvent = aiocbp;
141
142 aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
143
144 aiocbp->aio_sigevent.sigev_signo = -1;
145
146 IoOperationStatus = ReadFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
147 aiocbp->aio_buf,
148 aiocbp->aio_nbytes,
149 Overlapped,
150 IoCompletionRoutine);
151
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 );
156 return -1;
157 }
158
159 /* The I/O queued successfully. Go back into the
160 alertable wait for I/O completion or for
161 more I/O requests. */
162 return 0;
163 }
164
165 int aio_write(struct aiocb *aiocbp)
166 {
167 LPOVERLAPPED Overlapped;
168 BOOL IoOperationStatus;
169
170 /* Allocate an overlapped structure. */
171 Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED));
172
173 if (!Overlapped) {
174 errno = ENOMEM;
175 return -1;
176 }
177
178 #if _FILE_OFFSET_BITS==64
179 #ifdef __GNUC__
180 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
181
182 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
183
184 #else
185
186 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
187
188 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
189
190 #endif
191 #else
192
193 Overlapped->Offset = aiocbp->aio_offset;
194
195 Overlapped->OffsetHigh = 0;
196
197 #endif
198
199 Overlapped->hEvent = aiocbp;
200
201 aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
202
203 aiocbp->aio_sigevent.sigev_signo = -1;
204
205 IoOperationStatus = WriteFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
206 aiocbp->aio_buf,
207 aiocbp->aio_nbytes,
208 Overlapped,
209 IoCompletionRoutine);
210
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 );
215 return -1;
216 }
217
218 /* The I/O queued successfully. Go back into the
219 alertable wait for I/O completion or for
220 more I/O requests. */
221 return 0;
222 }
223
224 int aio_write64(struct aiocb64 *aiocbp)
225 {
226 LPOVERLAPPED Overlapped;
227 BOOL IoOperationStatus;
228
229 /* Allocate an overlapped structure. */
230 Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED));
231
232 if (!Overlapped) {
233 errno = ENOMEM;
234 return -1;
235 }
236
237 #ifdef __GNUC__
238 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
239
240 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
241
242 #else
243
244 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
245
246 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
247
248 #endif
249
250 Overlapped->hEvent = aiocbp;
251
252 aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
253
254 aiocbp->aio_sigevent.sigev_signo = -1;
255
256 IoOperationStatus = WriteFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
257 aiocbp->aio_buf,
258 aiocbp->aio_nbytes,
259 Overlapped,
260 IoCompletionRoutine);
261
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 );
266 return -1;
267 }
268
269 /* The I/O queued successfully. Go back into the
270 alertable wait for I/O completion or for
271 more I/O requests. */
272 return 0;
273 }
274
275 int aio_error(const struct aiocb * aiocbp)
276 {
277 return aiocbp->aio_sigevent.sigev_notify;
278 }
279
280 int aio_error64(const struct aiocb64 * aiocbp)
281 {
282 return aiocbp->aio_sigevent.sigev_notify;
283 }
284
285 int aio_open(const char *path, int mode)
286 {
287 HANDLE hndl;
288 DWORD dwCreationDisposition;
289 DWORD dwDesiredAccess;
290 int fd;
291
292 if (mode & O_WRONLY)
293 mode |= O_APPEND;
294
295 mode |= O_BINARY;
296
297 errno = 0;
298
299 if (mode & O_WRONLY)
300 dwDesiredAccess = GENERIC_WRITE;
301 else
302 dwDesiredAccess = (mode & O_RDONLY) ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE;
303
304 if (mode & O_TRUNC)
305 dwCreationDisposition = CREATE_ALWAYS;
306 else
307 dwCreationDisposition = (mode & O_CREAT) ? OPEN_ALWAYS : OPEN_EXISTING;
308
309 if ((hndl = CreateFile(path, /* file name */
310 dwDesiredAccess, /* access mode */
311 0, /* share mode */
312 NULL, /* SD */
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);
321 } else {
322 errno = GetLastError();
323 fd = DISK_ERROR;
324 }
325
326 return fd;
327 }
328
329 void aio_close(int fd)
330 {
331 CloseHandle((HANDLE)_get_osfhandle(fd));
332 fd_close(fd);
333 ++ statCounter.syscalls.disk.closes;
334 }
335
336 ssize_t aio_return(struct aiocb * aiocbp)
337 {
338 return aiocbp->aio_sigevent.sigev_signo;
339 }
340
341 ssize_t aio_return64(struct aiocb64 * aiocbp)
342
343 {
344 return aiocbp->aio_sigevent.sigev_signo;
345 }
346 #endif /* _SQUID_WINDOWS_ */