Home | History | Annotate | Download | only in include
      1 #ifndef _LIBAIO_H
      2 #define _LIBAIO_H
      3 
      4 // Don't include the actual header uapi/aio_abi.h
      5 // since libaio redefines the structs for some reason.
      6 // Instead override those definitions with the ones below.
      7 #define __LINUX__AIO_ABI_H
      8 
      9 #include <stdint.h>
     10 
     11 #if __UINTPTR_MAX__ == UINT64_MAX
     12 #define PADDED_PTR(x, y) x
     13 #elif __UINTPTR_MAX__ == UINT32_MAX
     14 #define PADDED_PTR(x, y) x; unsigned y
     15 #endif
     16 
     17 struct io_iocb_common {
     18     PADDED_PTR(void *buf, __pad1);
     19     __u64 nbytes;
     20     __s64    offset;
     21     __u64    reserved2;
     22     __u32    flags;
     23     __u32    resfd;
     24 };
     25 
     26 struct iocb {
     27     PADDED_PTR(void *data, __pad1);
     28     __u32 key;
     29     __u32 aio_rw_flags;
     30     __u16 aio_lio_opcode;
     31     __s16 aio_reqprio;
     32     __u32 aio_fildes;
     33     union {
     34         struct io_iocb_common c;
     35     } u;
     36 };
     37 
     38 struct io_event {
     39     PADDED_PTR(void *data, __pad1);
     40     PADDED_PTR(struct iocb *obj, __pad2);
     41     __s64 res;
     42     __s64 res2;
     43 };
     44 
     45 typedef unsigned long io_context_t;
     46 typedef io_context_t aio_context_t;
     47 
     48 #include <asyncio/AsyncIO.h>
     49 
     50 #define IO_CMD_PREAD 0
     51 #define IO_CMD_PWRITE 1
     52 #define IO_CMD_FSYNC 2
     53 #define IO_CMD_FDSYNC 3
     54 #define IO_CMD_POLL 5
     55 #define IO_CMD_NOOP 6
     56 #define IO_CMD_PREADV 7
     57 #define IO_CMD_PWRITEV 8
     58 
     59 typedef void (*io_callback_t)(io_context_t ctx, struct iocb *iocb, long res, long res2);
     60 
     61 static inline int redirect_error(int ret) {
     62     return ret == -1 ? -errno : ret;
     63 }
     64 
     65 // libaio doesn't follow syscall convention, so errors are returned
     66 // as negative values and errno isn't used.
     67 
     68 static inline int libaio_setup(int maxevents, io_context_t *ctxp) {
     69     int ret = io_setup(maxevents, ctxp);
     70     return redirect_error(ret);
     71 }
     72 
     73 static inline int libaio_destroy(io_context_t ctx) {
     74     int ret = io_destroy(ctx);
     75     return redirect_error(ret);
     76 }
     77 
     78 static inline int libaio_submit(io_context_t ctx, long nr, struct iocb *ios[]) {
     79     int ret = io_submit(ctx, nr, ios);
     80     return redirect_error(ret);
     81 }
     82 
     83 static inline int libaio_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt) {
     84     int ret = io_cancel(ctx, iocb, evt);
     85     return redirect_error(ret);
     86 }
     87 
     88 static inline int libaio_getevents(io_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout) {
     89     int ret = io_getevents(ctx_id, min_nr, nr, events, timeout);
     90     return redirect_error(ret);
     91 }
     92 
     93 static inline void io_set_callback(struct iocb *iocb, io_callback_t cb)
     94 {
     95     iocb->data = (void *)cb;
     96 }
     97 
     98 static inline int io_queue_init(int maxevents, io_context_t *ctxp) {
     99     memset(ctxp, 0, sizeof(*ctxp));
    100     return libaio_setup(maxevents, ctxp);
    101 }
    102 
    103 // Override the system calls with their libaio versions.
    104 
    105 #define io_setup(a, b) libaio_setup(a, b)
    106 #define io_destroy(a) libaio_destroy(a)
    107 #define io_submit(a, b, c) libaio_submit(a, b, c)
    108 #define io_cancel(a, b, c) libaio_cancel(a, b, c)
    109 #define io_getevents(a, b, c, d, e) libaio_getevents(a, b, c, d, e)
    110 
    111 #define io_queue_release(a) io_destroy(a)
    112 
    113 #endif
    114