diff options
Diffstat (limited to 'src/aio_event.c')
-rw-r--r-- | src/aio_event.c | 102 |
1 files changed, 63 insertions, 39 deletions
diff --git a/src/aio_event.c b/src/aio_event.c index 465ce4c79..9bd952e1f 100644 --- a/src/aio_event.c +++ b/src/aio_event.c @@ -35,6 +35,7 @@ #define MAX_AIO_EV 32768 struct io_cbdata { + gint fd; rspamd_aio_cb cb; gsize len; gpointer buf; @@ -58,33 +59,53 @@ typedef enum io_iocb_cmd { IO_CMD_NOOP = 6, } io_iocb_cmd_t; -struct io_iocb_common { - void *buf; - unsigned __pad1; - long nbytes; - unsigned __pad2; - long long offset; - long long __pad3; - unsigned flags; - unsigned resfd; -}; /* result code is the amount read or -'ve errno */ +#if defined(__LITTLE_ENDIAN) +#define PADDED(x,y) x, y +#elif defined(__BIG_ENDIAN) +#define PADDED(x,y) y, x +#else +#error edit for your odd byteorder. +#endif + +/* + * we always use a 64bit off_t when communicating + * with userland. its up to libraries to do the + * proper padding and aio_error abstraction + */ struct iocb { - void *data; - unsigned key; - short aio_lio_opcode; - short aio_reqprio; - int aio_fildes; - union { - struct io_iocb_common c; - } u; + /* these are internal to the kernel/libc. */ + guint64 aio_data; /* data to be returned in event's data */ + guint32 PADDED(aio_key, aio_reserved1); + /* the kernel sets aio_key to the req # */ + + /* common fields */ + guint16 aio_lio_opcode; /* see IOCB_CMD_ above */ + gint16 aio_reqprio; + guint32 aio_fildes; + + guint64 aio_buf; + guint64 aio_nbytes; + guint64 aio_offset; + + /* extra parameters */ + guint64 aio_reserved2; /* TODO: use this for a (struct sigevent *) */ + + /* flags for the "struct iocb" */ + guint32 aio_flags; + + /* + * if the IOCB_FLAG_RESFD flag of "aio_flags" is set, this is an + * eventfd to signal AIO readiness to + */ + guint32 aio_resfd; }; struct io_event { - uint64_t data; /* the data field from the iocb */ - uint64_t obj; /* what iocb this event came from */ - int64_t res; /* result code for this event */ - int64_t res2; /* secondary result */ + guint64 data; /* the data field from the iocb */ + guint64 obj; /* what iocb this event came from */ + gint64 res; /* result code for this event */ + gint64 res2; /* secondary result */ }; /* Linux specific io calls */ @@ -178,7 +199,7 @@ rspamd_eventfdcb (gint fd, gshort what, gpointer ud) for (i = 0; i < done; i ++) { ev_data = (struct io_cbdata *) (uintptr_t) event[i].data; /* Call this callback */ - ev_data->cb (event[i].res, ev_data->len, ev_data->buf, ev_data->ud); + ev_data->cb (ev_data->fd, event[i].res, ev_data->len, ev_data->buf, ev_data->ud); } } else if (done == 0) { @@ -221,6 +242,7 @@ rspamd_aio_init (struct event_base *base) else { event_set (&new->eventfd_ev, new->event_fd, EV_READ|EV_PERSIST, rspamd_eventfdcb, new); event_base_set (new->base, &new->eventfd_ev); + event_add (&new->eventfd_ev, NULL); if (io_setup (MAX_AIO_EV, &new->io_ctx) == -1) { msg_err ("io_setup failed: %s", strerror (errno)); close (new->event_fd); @@ -278,18 +300,19 @@ rspamd_aio_read (gint fd, gpointer buf, gsize len, struct aio_context *ctx, rspa cbdata->buf = buf; cbdata->len = len; cbdata->ud = ud; + cbdata->fd = fd; iocb[0] = alloca (sizeof (struct iocb)); memset (iocb[0], 0, sizeof (struct iocb)); iocb[0]->aio_fildes = fd; iocb[0]->aio_lio_opcode = IO_CMD_PREAD; iocb[0]->aio_reqprio = 0; - iocb[0]->u.c.buf = buf; - iocb[0]->u.c.nbytes = len; - iocb[0]->u.c.offset = 0; - iocb[0]->u.c.flags |= (1 << 0) /* IOCB_FLAG_RESFD */; - iocb[0]->u.c.resfd = ctx->event_fd; - iocb[0]->data = cbdata; + iocb[0]->aio_buf = (guint64)((uintptr_t)buf); + iocb[0]->aio_nbytes = len; + iocb[0]->aio_offset = 0; + iocb[0]->aio_flags |= (1 << 0) /* IOCB_FLAG_RESFD */; + iocb[0]->aio_resfd = ctx->event_fd; + iocb[0]->aio_data = (guint64)((uintptr_t)cbdata); /* Iocb is copied to kernel internally, so it is safe to put it on stack */ if (io_submit (ctx->io_ctx, 1, iocb) == 1) { @@ -311,10 +334,10 @@ rspamd_aio_read (gint fd, gpointer buf, gsize len, struct aio_context *ctx, rspa blocking: r = read (fd, buf, len); if (r >= 0) { - cb (0, r, buf, ud); + cb (fd, 0, r, buf, ud); } else { - cb (r, -1, buf, ud); + cb (fd, r, -1, buf, ud); } } @@ -339,18 +362,19 @@ rspamd_aio_write (gint fd, gpointer buf, gsize len, struct aio_context *ctx, rsp cbdata->buf = buf; cbdata->len = len; cbdata->ud = ud; + cbdata->fd = fd; iocb[0] = alloca (sizeof (struct iocb)); memset (iocb[0], 0, sizeof (struct iocb)); iocb[0]->aio_fildes = fd; iocb[0]->aio_lio_opcode = IO_CMD_PWRITE; iocb[0]->aio_reqprio = 0; - iocb[0]->u.c.buf = buf; - iocb[0]->u.c.nbytes = len; - iocb[0]->u.c.offset = 0; - iocb[0]->u.c.flags |= (1 << 0) /* IOCB_FLAG_RESFD */; - iocb[0]->u.c.resfd = ctx->event_fd; - iocb[0]->data = cbdata; + iocb[0]->aio_buf = (guint64)((uintptr_t)buf); + iocb[0]->aio_nbytes = len; + iocb[0]->aio_offset = 0; + iocb[0]->aio_flags |= (1 << 0) /* IOCB_FLAG_RESFD */; + iocb[0]->aio_resfd = ctx->event_fd; + iocb[0]->aio_data = (guint64)((uintptr_t)cbdata); /* Iocb is copied to kernel internally, so it is safe to put it on stack */ if (io_submit (ctx->io_ctx, 1, iocb) == 1) { @@ -372,10 +396,10 @@ rspamd_aio_write (gint fd, gpointer buf, gsize len, struct aio_context *ctx, rsp blocking: r = write (fd, buf, len); if (r >= 0) { - cb (0, r, buf, ud); + cb (fd, 0, r, buf, ud); } else { - cb (r, -1, buf, ud); + cb (fd, r, -1, buf, ud); } } |