source: squid-ssl/trunk/fuentes/src/DiskIO/AIO/aio_win32.cc @ 5495

Last change on this file since 5495 was 5495, checked in by Juanma, 4 years ago

Initial release

File size: 8.6 KB
Line 
1/*
2 * Copyright (C) 1996-2015 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"
13#include "DiskIO/AIO/aio_win32.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                           NULL,                    /* SD                      */
291                           dwCreationDisposition,   /* how to create           */
292                           FILE_FLAG_OVERLAPPED,    /* file attributes         */
293                           NULL                     /* handle to template file */
294                          )) != INVALID_HANDLE_VALUE) {
295        ++ statCounter.syscalls.disk.opens;
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
307void aio_close(int fd)
308{
309    CloseHandle((HANDLE)_get_osfhandle(fd));
310    fd_close(fd);
311    ++ statCounter.syscalls.disk.closes;
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
Note: See TracBrowser for help on using the repository browser.