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 }