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 */ 9module core.sys.posix.aio; 10 11import core.sys.posix.signal; 12import core.sys.posix.sys.types; 13 14version (OSX) 15 version = Darwin; 16else version (iOS) 17 version = Darwin; 18else version (TVOS) 19 version = Darwin; 20else version (WatchOS) 21 version = Darwin; 22 23version (Posix): 24 25extern (C): 26@system: 27@nogc: 28nothrow: 29 30version (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} 75else version (CRuntime_Bionic) 76{ 77 // Bionic does not define aiocb. 78} 79else 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} 100else version (CRuntime_UClibc) 101{ 102 // UClibc does not implement aiocb. 103} 104else 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} 117else 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} 142else 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} 160else version (OpenBSD) 161{ 162 // OpenBSD does not define aiocb. 163} 164else 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} 181else 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} 203else 204 static assert(false, "Unsupported platform"); 205 206/* Return values of cancelation function. */ 207version (CRuntime_Glibc) 208{ 209 enum 210 { 211 AIO_CANCELED, 212 AIO_NOTCANCELED, 213 AIO_ALLDONE 214 } 215} 216else version (CRuntime_Musl) 217{ 218 enum 219 { 220 AIO_CANCELED, 221 AIO_NOTCANCELED, 222 AIO_ALLDONE 223 } 224} 225else version (Darwin) 226{ 227 enum 228 { 229 AIO_ALLDONE = 0x1, 230 AIO_CANCELED = 0x2, 231 AIO_NOTCANCELED = 0x4, 232 } 233} 234else version (Solaris) 235{ 236 enum 237 { 238 AIO_CANCELED, 239 AIO_ALLDONE, 240 AIO_NOTCANCELED 241 } 242} 243else 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'. */ 254version (CRuntime_Glibc) 255{ 256 enum 257 { 258 LIO_READ, 259 LIO_WRITE, 260 LIO_NOP 261 } 262} 263else version (CRuntime_Musl) 264{ 265 enum 266 { 267 LIO_READ, 268 LIO_WRITE, 269 LIO_NOP 270 } 271} 272else version (Darwin) 273{ 274 enum 275 { 276 LIO_NOP = 0x0, 277 LIO_READ = 0x1, 278 LIO_WRITE = 0x2, 279 } 280} 281else version (Solaris) 282{ 283 enum 284 { 285 LIO_NOP, 286 LIO_READ, 287 LIO_WRITE, 288 } 289} 290else 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. */ 301version (CRuntime_Glibc) 302{ 303 enum 304 { 305 LIO_WAIT, 306 LIO_NOWAIT 307 } 308} 309else version (CRuntime_Musl) 310{ 311 enum 312 { 313 LIO_WAIT, 314 LIO_NOWAIT 315 } 316} 317else version (Darwin) 318{ 319 enum 320 { 321 LIO_NOWAIT = 0x1, 322 LIO_WAIT = 0x2, 323 } 324} 325else version (Solaris) 326{ 327 enum 328 { 329 LIO_NOWAIT, 330 LIO_WAIT 331 } 332} 333else version (BSD_Posix) 334{ 335 enum 336 { 337 LIO_NOWAIT, 338 LIO_WAIT 339 } 340} 341 342/* Functions implementing POSIX AIO. */ 343version (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} 377else version (CRuntime_Bionic) 378{ 379 // Bionic does not implement aio.h 380} 381else version (CRuntime_UClibc) 382{ 383 // UClibc does not implement aio.h 384} 385else version (OpenBSD) 386{ 387 // OpenBSD does not implement aio.h 388} 389else 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 int aio_suspend(const(aiocb*)* aiocb_list, int nitems, const(timespec)* timeout); 397 int aio_cancel(int fd, aiocb* aiocbp); 398 int lio_listio(int mode, const(aiocb*)* aiocb_list, int nitems, sigevent* sevp); 399} 400 401/* Functions outside/extending POSIX requirement. */ 402version (CRuntime_Glibc) 403{ 404 static if (_GNU_SOURCE) 405 { 406 /* To customize the implementation one can use the following struct. */ 407 struct aioinit 408 { 409 int aio_threads; 410 int aio_num; 411 int aio_locks; 412 int aio_usedba; 413 int aio_debug; 414 int aio_numusers; 415 int aio_idle_time; 416 int aio_reserved; 417 } 418 419 void aio_init(const(aioinit)* init); 420 } 421} 422else version (FreeBSD) 423{ 424 int aio_waitcomplete(aiocb** aiocb_list, const(timespec)* timeout); 425 int aio_mlock(aiocb* aiocbp); 426} 427else version (DragonFlyBSD) 428{ 429 int aio_waitcomplete(aiocb** aiocb_list, const(timespec)* timeout); 430} 431