1 /**
2 * D header file to interface with the
3 * $(HTTP pubs.opengroup.org/onlinepubs/9699919799/basedefs/aio.h.html, Posix AIO API).
4 *
5 * Copyright: Copyright D Language Foundation 2018.
6 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7 * Authors: $(HTTPS github.com/darredevil, Alexandru Razvan Caciulescu)
8 */
9 module core.sys.posix.aio;
10
11 import core.stdc.config;
12 import core.sys.posix.signal;
13 import core.sys.posix.sys.types;
14
15 version (OSX)
16 version = Darwin;
17 else version (iOS)
18 version = Darwin;
19 else version (TVOS)
20 version = Darwin;
21 else version (WatchOS)
22 version = Darwin;
23
24 version (Posix):
25
26 extern (C):
27 @nogc:
28 nothrow:
29
30 version (CRuntime_Glibc)
31 {
32 import core.sys.posix.config;
33
34 struct aiocb
35 {
36 int aio_fildes;
37 int aio_lio_opcode;
38 int aio_reqprio;
39 void* aio_buf; //volatile
40 size_t aio_nbytes;
41 sigevent aio_sigevent;
42
43 aiocb* __next_prio;
44 int __abs_prio;
45 int __policy;
46 int __error_code;
47 ssize_t __return_value;
48
49 off_t aio_offset;
50 ubyte[32] __glibc_reserved;
51 }
52
53 static if (__USE_LARGEFILE64)
54 {
55 struct aiocb64
56 {
57 int aio_fildes;
58 int aio_lio_opcode;
59 int aio_reqprio;
60 void* aio_buf; //volatile
61 size_t aio_nbytes;
62 sigevent aio_sigevent;
63
64 aiocb* __next_prio;
65 int __abs_prio;
66 int __policy;
67 int __error_code;
68 ssize_t __return_value;
69
70 off_t aio_offset;
71 ubyte[32] __glibc_reserved;
72 }
73 }
74 }
75 else version (CRuntime_Bionic)
76 {
77 // Bionic does not define aiocb.
78 }
79 else version (CRuntime_Musl)
80 {
81 // https://git.musl-libc.org/cgit/musl/tree/include/aio.h
82 struct aiocb
83 {
84 int aio_fildes;
85 int aio_lio_opcode;
86 int aio_reqprio;
87 void* aio_buf; //volatile
88 size_t aio_nbytes;
89 sigevent aio_sigevent;
90 void* __td;
91 int[2] __lock;
92 int __err; //volatile
93 ssize_t __ret;
94 off_t aio_offset;
95 void* __next;
96 void* __prev;
97 ubyte[32-2*(void*).sizeof] __dummy4;
98 }
99 }
100 else version (CRuntime_UClibc)
101 {
102 // UClibc does not implement aiocb.
103 }
104 else version (Darwin)
105 {
106 struct aiocb
107 {
108 int aio_filedes;
109 off_t aio_offset;
110 void* aio_buf; // volatile
111 size_t aio_nbytes;
112 int reqprio;
113 sigevent aio_sigevent;
114 int aio_lio_opcode;
115 }
116 }
117 else version (FreeBSD)
118 {
119 struct __aiocb_private
120 {
121 long status;
122 long error;
123 void* kernelinfo;
124 }
125
126 struct aiocb
127 {
128 int aio_fildes;
129 off_t aio_offset;
130 void* aio_buf; // volatile
131 size_t aio_nbytes;
132 private int[2] __spare;
133 private void* _spare2__;
134 int aio_lio_opcode;
135 int aio_reqprio;
136 private __aiocb_private _aiocb_private;
137 sigevent aio_sigevent;
138 }
139
140 version = BSD_Posix;
141 }
142 else version (NetBSD)
143 {
144 struct aiocb
145 {
146 off_t aio_offset;
147 void* aio_buf; // volatile
148 size_t aio_nbytes;
149 int aio_fildes;
150 int aio_lio_opcode;
151 int aio_reqprio;
152 sigevent aio_sigevent;
153 private int _state;
154 private int _errno;
155 private ssize_t _retval;
156 }
157
158 version = BSD_Posix;
159 }
160 else version (OpenBSD)
161 {
162 // OpenBSD does not define aiocb.
163 }
164 else version (DragonFlyBSD)
165 {
166 struct aiocb
167 {
168 int aio_fildes;
169 off_t aio_offset;
170 void* aio_buf; // volatile
171 size_t aio_nbytes;
172 sigevent aio_sigevent;
173 int aio_lio_opcode;
174 int aio_reqprio;
175 private int _aio_val;
176 private int _aio_err;
177 }
178
179 version = BSD_Posix;
180 }
181 else version (Solaris)
182 {
183 struct aio_result_t
184 {
185 ssize_t aio_return;
186 int aio_errno;
187 }
188
189 struct aiocb
190 {
191 int aio_fildes;
192 void* aio_buf; // volatile
193 size_t aio_nbytes;
194 off_t aio_offset;
195 int aio_reqprio;
196 sigevent aio_sigevent;
197 int aio_lio_opcode;
198 aio_result_t aio_resultp;
199 int aio_state;
200 int[1] aio__pad;
201 }
202 }
203 else
204 static assert(false, "Unsupported platform");
205
206 /* Return values of cancelation function. */
207 version (CRuntime_Glibc)
208 {
209 enum
210 {
211 AIO_CANCELED,
212 AIO_NOTCANCELED,
213 AIO_ALLDONE
214 }
215 }
216 else version (CRuntime_Musl)
217 {
218 enum
219 {
220 AIO_CANCELED,
221 AIO_NOTCANCELED,
222 AIO_ALLDONE
223 }
224 }
225 else version (Darwin)
226 {
227 enum
228 {
229 AIO_ALLDONE = 0x1,
230 AIO_CANCELED = 0x2,
231 AIO_NOTCANCELED = 0x4,
232 }
233 }
234 else version (Solaris)
235 {
236 enum
237 {
238 AIO_CANCELED,
239 AIO_ALLDONE,
240 AIO_NOTCANCELED
241 }
242 }
243 else version (BSD_Posix)
244 {
245 enum
246 {
247 AIO_CANCELED,
248 AIO_NOTCANCELED,
249 AIO_ALLDONE
250 }
251 }
252
253 /* Operation codes for `aio_lio_opcode'. */
254 version (CRuntime_Glibc)
255 {
256 enum
257 {
258 LIO_READ,
259 LIO_WRITE,
260 LIO_NOP
261 }
262 }
263 else version (CRuntime_Musl)
264 {
265 enum
266 {
267 LIO_READ,
268 LIO_WRITE,
269 LIO_NOP
270 }
271 }
272 else version (Darwin)
273 {
274 enum
275 {
276 LIO_NOP = 0x0,
277 LIO_READ = 0x1,
278 LIO_WRITE = 0x2,
279 }
280 }
281 else version (Solaris)
282 {
283 enum
284 {
285 LIO_NOP,
286 LIO_READ,
287 LIO_WRITE,
288 }
289 }
290 else version (BSD_Posix)
291 {
292 enum
293 {
294 LIO_NOP,
295 LIO_WRITE,
296 LIO_READ
297 }
298 }
299
300 /* Synchronization options for `lio_listio' function. */
301 version (CRuntime_Glibc)
302 {
303 enum
304 {
305 LIO_WAIT,
306 LIO_NOWAIT
307 }
308 }
309 else version (CRuntime_Musl)
310 {
311 enum
312 {
313 LIO_WAIT,
314 LIO_NOWAIT
315 }
316 }
317 else version (Darwin)
318 {
319 enum
320 {
321 LIO_NOWAIT = 0x1,
322 LIO_WAIT = 0x2,
323 }
324 }
325 else version (Solaris)
326 {
327 enum
328 {
329 LIO_NOWAIT,
330 LIO_WAIT
331 }
332 }
333 else version (BSD_Posix)
334 {
335 enum
336 {
337 LIO_NOWAIT,
338 LIO_WAIT
339 }
340 }
341
342 /* Functions implementing POSIX AIO. */
343 version (CRuntime_Glibc)
344 {
345 static if (__USE_LARGEFILE64)
346 {
347 int aio_read64(aiocb64* aiocbp);
348 int aio_write64(aiocb64* aiocbp);
349 int aio_fsync64(int op, aiocb64* aiocbp);
350 int aio_error64(const(aiocb64)* aiocbp);
351 ssize_t aio_return64(aiocb64* aiocbp);
352 int aio_suspend64(const(aiocb64*)* aiocb_list, int nitems, const(timespec)* timeout);
353 int aio_cancel64(int fd, aiocb64* aiocbp);
354 int lio_listio64(int mode, const(aiocb64*)* aiocb_list, int nitems, sigevent* sevp);
355
356 alias aio_read = aio_read64;
357 alias aio_write = aio_write64;
358 alias aio_fsync = aio_fsync64;
359 alias aio_error = aio_error64;
360 alias aio_return = aio_return64;
361 alias aio_suspend = aio_suspend64;
362 alias aio_cancel = aio_cancel64;
363 alias lio_listio = lio_listio64;
364 }
365 else
366 {
367 int aio_read(aiocb* aiocbp);
368 int aio_write(aiocb* aiocbp);
369 int aio_fsync(int op, aiocb* aiocbp);
370 int aio_error(const(aiocb)* aiocbp);
371 ssize_t aio_return(aiocb* aiocbp);
372 int aio_suspend(const(aiocb*)* aiocb_list, int nitems, const(timespec)* timeout);
373 int aio_cancel(int fd, aiocb* aiocbp);
374 int lio_listio(int mode, const(aiocb*)* aiocb_list, int nitems, sigevent* sevp);
375 }
376 }
377 else version (CRuntime_Bionic)
378 {
379 // Bionic does not implement aio.h
380 }
381 else version (CRuntime_UClibc)
382 {
383 // UClibc does not implement aio.h
384 }
385 else version (OpenBSD)
386 {
387 // OpenBSD does not implement aio.h
388 }
389 else
390 {
391 int aio_read(aiocb* aiocbp);
392 int aio_write(aiocb* aiocbp);
393 int aio_fsync(int op, aiocb* aiocbp);
394 int aio_error(const(aiocb)* aiocbp);
395 ssize_t aio_return(aiocb* aiocbp);
396 pragma(mangle, muslRedirTime64Mangle!("aio_suspend", "__aio_suspend_time64"))
397 int aio_suspend(const(aiocb*)* aiocb_list, int nitems, const(timespec)* timeout);
398 int aio_cancel(int fd, aiocb* aiocbp);
399 int lio_listio(int mode, const(aiocb*)* aiocb_list, int nitems, sigevent* sevp);
400 }
401
402 /* Functions outside/extending POSIX requirement. */
403 version (CRuntime_Glibc)
404 {
405 static if (_GNU_SOURCE)
406 {
407 /* To customize the implementation one can use the following struct. */
408 struct aioinit
409 {
410 int aio_threads;
411 int aio_num;
412 int aio_locks;
413 int aio_usedba;
414 int aio_debug;
415 int aio_numusers;
416 int aio_idle_time;
417 int aio_reserved;
418 }
419
420 void aio_init(const(aioinit)* init);
421 }
422 }
423 else version (FreeBSD)
424 {
425 int aio_waitcomplete(aiocb** aiocb_list, const(timespec)* timeout);
426 int aio_mlock(aiocb* aiocbp);
427 }
428 else version (DragonFlyBSD)
429 {
430 int aio_waitcomplete(aiocb** aiocb_list, const(timespec)* timeout);
431 }