]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DiskIO/AIO/aio_win32.cc
Merged from trunk
[thirdparty/squid.git] / src / DiskIO / AIO / aio_win32.cc
1
2 /*
3 * $Id: aio_win32.cc,v 1.3 2007/04/28 22:26:40 hno Exp $
4 *
5 * DEBUG: section 81 aio_xxx() POSIX emulation on Windows
6 * AUTHOR: Guido Serassio <serassio@squid-cache.org>
7 *
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
10 *
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.
19 *
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.
24 *
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.
29 *
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.
33 *
34 */
35
36 #include "squid.h"
37 #include "comm.h"
38 #include "aio_win32.h"
39
40 #ifdef _SQUID_WIN32_
41 VOID CALLBACK IoCompletionRoutine(DWORD dwErrorCode,
42 DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
43 {
44
45 struct aiocb *aiocbp = (struct aiocb *) lpOverlapped->hEvent;
46
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);
50 xfree(lpOverlapped);
51 }
52
53
54 int aio_read(struct aiocb *aiocbp)
55 {
56 LPOVERLAPPED Overlapped;
57 BOOL IoOperationStatus;
58
59 /* Allocate an overlapped structure. */
60 Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED));
61
62 if (!Overlapped) {
63 errno = ENOMEM;
64 return -1;
65 }
66
67 #if _FILE_OFFSET_BITS==64
68 #ifdef __GNUC__
69 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
70
71 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
72
73 #else
74
75 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
76
77 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
78
79 #endif
80 #else
81
82 Overlapped->Offset = aiocbp->aio_offset;
83
84 Overlapped->OffsetHigh = 0;
85
86 #endif
87
88 Overlapped->hEvent = aiocbp;
89
90 aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
91
92 aiocbp->aio_sigevent.sigev_signo = -1;
93
94 IoOperationStatus = ReadFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
95 aiocbp->aio_buf,
96 aiocbp->aio_nbytes,
97 Overlapped,
98 IoCompletionRoutine);
99
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 );
104 return -1;
105 }
106
107 /* The I/O queued successfully. Go back into the
108 alertable wait for I/O completion or for
109 more I/O requests. */
110 return 0;
111 }
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, 1, "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
166 int aio_write(struct aiocb *aiocbp)
167 {
168 LPOVERLAPPED Overlapped;
169 BOOL IoOperationStatus;
170
171 /* Allocate an overlapped structure. */
172 Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED));
173
174 if (!Overlapped) {
175 errno = ENOMEM;
176 return -1;
177 }
178
179 #if _FILE_OFFSET_BITS==64
180 #ifdef __GNUC__
181 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
182
183 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
184
185 #else
186
187 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
188
189 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
190
191 #endif
192 #else
193
194 Overlapped->Offset = aiocbp->aio_offset;
195
196 Overlapped->OffsetHigh = 0;
197
198 #endif
199
200 Overlapped->hEvent = aiocbp;
201
202 aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
203
204 aiocbp->aio_sigevent.sigev_signo = -1;
205
206 IoOperationStatus = WriteFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
207 aiocbp->aio_buf,
208 aiocbp->aio_nbytes,
209 Overlapped,
210 IoCompletionRoutine);
211
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 );
216 return -1;
217 }
218
219 /* The I/O queued successfully. Go back into the
220 alertable wait for I/O completion or for
221 more I/O requests. */
222 return 0;
223 }
224
225
226 int aio_write64(struct aiocb64 *aiocbp)
227 {
228 LPOVERLAPPED Overlapped;
229 BOOL IoOperationStatus;
230
231 /* Allocate an overlapped structure. */
232 Overlapped = (LPOVERLAPPED) xcalloc(1, sizeof(OVERLAPPED));
233
234 if (!Overlapped) {
235 errno = ENOMEM;
236 return -1;
237 }
238
239 #ifdef __GNUC__
240 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000LL);
241
242 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000LL);
243
244 #else
245
246 Overlapped->Offset = (DWORD) (aiocbp->aio_offset % 0x100000000);
247
248 Overlapped->OffsetHigh = (DWORD) (aiocbp->aio_offset / 0x100000000);
249
250 #endif
251
252 Overlapped->hEvent = aiocbp;
253
254 aiocbp->aio_sigevent.sigev_notify = EINPROGRESS;
255
256 aiocbp->aio_sigevent.sigev_signo = -1;
257
258 IoOperationStatus = WriteFileEx((HANDLE)_get_osfhandle(aiocbp->aio_fildes),
259 aiocbp->aio_buf,
260 aiocbp->aio_nbytes,
261 Overlapped,
262 IoCompletionRoutine);
263
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 );
268 return -1;
269 }
270
271 /* The I/O queued successfully. Go back into the
272 alertable wait for I/O completion or for
273 more I/O requests. */
274 return 0;
275 }
276
277
278 int aio_error(const struct aiocb * aiocbp)
279 {
280 return aiocbp->aio_sigevent.sigev_notify;
281 }
282
283
284 int aio_error64(const struct aiocb64 * aiocbp)
285 {
286 return aiocbp->aio_sigevent.sigev_notify;
287 }
288
289
290 int aio_open(const char *path, int mode)
291 {
292 HANDLE hndl;
293 DWORD dwCreationDisposition;
294 DWORD dwDesiredAccess;
295 int fd;
296
297 if (mode & O_WRONLY)
298 mode |= O_APPEND;
299
300 mode |= O_BINARY;
301
302 errno = 0;
303
304 if (mode & O_WRONLY)
305 dwDesiredAccess = GENERIC_WRITE;
306 else
307 dwDesiredAccess = (mode & O_RDONLY) ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE;
308
309 if (mode & O_TRUNC)
310 dwCreationDisposition = CREATE_ALWAYS;
311 else
312 dwCreationDisposition = (mode & O_CREAT) ? OPEN_ALWAYS : OPEN_EXISTING;
313
314 if ((hndl = CreateFile(path, /* file name */
315 dwDesiredAccess, /* access mode */
316 0, /* share mode */
317 NULL, /* SD */
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);
326 } else {
327 errno = GetLastError();
328 fd = DISK_ERROR;
329 }
330
331 return fd;
332 }
333
334
335 void aio_close(int fd)
336 {
337 CloseHandle((HANDLE)_get_osfhandle(fd));
338 fd_close(fd);
339 statCounter.syscalls.disk.closes++;
340 }
341
342
343 ssize_t aio_return(struct aiocb * aiocbp)
344 {
345 return aiocbp->aio_sigevent.sigev_signo;
346 }
347
348
349 ssize_t aio_return64(struct aiocb64 * aiocbp)
350
351 {
352 return aiocbp->aio_sigevent.sigev_signo;
353 }
354 #endif /* _SQUID_WIN32_ */