]>
Commit | Line | Data |
---|---|---|
abb2a3d9 | 1 | |
2 | /* | |
262a0e14 | 3 | * $Id$ |
abb2a3d9 | 4 | * |
5 | * DEBUG: section 81 aio_xxx() POSIX emulation on Windows | |
1b52df9a | 6 | * AUTHOR: Guido Serassio <serassio@squid-cache.org> |
abb2a3d9 | 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. | |
26ac0430 | 24 | * |
abb2a3d9 | 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. | |
26ac0430 | 29 | * |
abb2a3d9 | 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 | ||
f7f3304a | 36 | #include "squid-old.h" |
abb2a3d9 | 37 | #include "comm.h" |
38 | #include "aio_win32.h" | |
39 | ||
be266cb2 | 40 | #if _SQUID_WINDOWS_ |
abb2a3d9 | 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; | |
bf8fe701 | 49 | debugs(81, 7, "AIO operation complete: errorcode=" << dwErrorCode << " nbytes=" << dwNumberOfBytesTransfered); |
abb2a3d9 | 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 | ||
26ac0430 | 62 | if (!Overlapped) { |
abb2a3d9 | 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. */ | |
26ac0430 | 101 | if (!IoOperationStatus) { |
abb2a3d9 | 102 | errno = GetLastError(); |
bf8fe701 | 103 | debugs(81,1, "aio_read: GetLastError=" << errno ); |
abb2a3d9 | 104 | return -1; |
105 | } | |
106 | ||
107 | /* The I/O queued successfully. Go back into the | |
26ac0430 | 108 | alertable wait for I/O completion or for |
abb2a3d9 | 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 | ||
26ac0430 | 122 | if (!Overlapped) { |
abb2a3d9 | 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. */ | |
26ac0430 | 153 | if (!IoOperationStatus) { |
abb2a3d9 | 154 | errno = GetLastError(); |
bf8fe701 | 155 | debugs(81, 1, "aio_read: GetLastError=" << errno ); |
abb2a3d9 | 156 | return -1; |
157 | } | |
158 | ||
159 | /* The I/O queued successfully. Go back into the | |
26ac0430 | 160 | alertable wait for I/O completion or for |
abb2a3d9 | 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 | ||
26ac0430 | 174 | if (!Overlapped) { |
abb2a3d9 | 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. */ | |
26ac0430 | 213 | if (!IoOperationStatus) { |
abb2a3d9 | 214 | errno = GetLastError(); |
bf8fe701 | 215 | debugs(81, 1, "aio_write: GetLastError=" << errno ); |
abb2a3d9 | 216 | return -1; |
217 | } | |
218 | ||
219 | /* The I/O queued successfully. Go back into the | |
26ac0430 | 220 | alertable wait for I/O completion or for |
abb2a3d9 | 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 | ||
26ac0430 | 234 | if (!Overlapped) { |
abb2a3d9 | 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. */ | |
26ac0430 | 265 | if (!IoOperationStatus) { |
abb2a3d9 | 266 | errno = GetLastError(); |
bf8fe701 | 267 | debugs(81, 1, "aio_write: GetLastError=" << errno ); |
abb2a3d9 | 268 | return -1; |
269 | } | |
270 | ||
271 | /* The I/O queued successfully. Go back into the | |
26ac0430 | 272 | alertable wait for I/O completion or for |
abb2a3d9 | 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 | } | |
be266cb2 | 354 | #endif /* _SQUID_WINDOWS_ */ |