]> source.dussan.org Git - rspamd.git/commitdiff
Aio context must be long not int.
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Sun, 11 Mar 2012 13:53:58 +0000 (17:53 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Sun, 11 Mar 2012 13:53:58 +0000 (17:53 +0400)
O_DIRECT on linux requires strict memory alignment.

src/aio_event.c
test/rspamd_async_test.c

index dc1d8284a237786a1d196ea779e49effcacc5dac..9dd0df35a78a796b715119fcb3003439958ba69d 100644 (file)
@@ -48,7 +48,7 @@
 #endif
 
 #define SYS_eventfd       323
-#define MAX_AIO_EV        32768
+#define MAX_AIO_EV        1024
 
 struct io_cbdata {
        gint fd;
@@ -62,7 +62,7 @@ struct io_cbdata {
 
 /* Linux specific mappings and utilities to avoid using of libaio */
 
-typedef unsigned int aio_context_t;
+typedef unsigned long aio_context_t;
 
 typedef enum io_iocb_cmd {
        IO_CMD_PREAD = 0,
@@ -102,7 +102,7 @@ struct iocb {
 
        guint64 aio_buf;
        guint64 aio_nbytes;
-       guint64 aio_offset;
+       gint64 aio_offset;
 
        /* extra parameters */
        guint64 aio_reserved2; /* TODO: use this for a (struct sigevent *) */
@@ -157,7 +157,7 @@ io_cancel (aio_context_t ctx, struct iocb *iocb, struct io_event *result)
 
 # ifndef HAVE_SYS_EVENTFD_H
 static int
-eventfd(guint initval, guint flags)
+eventfd (guint initval, guint flags)
 {
        return syscall (SYS_eventfd, initval);
 }
@@ -176,6 +176,8 @@ struct aio_context {
        gint event_fd;
        struct event eventfd_ev;
        aio_context_t io_ctx;
+       gpointer buf;
+       gsize buflen;
 #elif defined(HAVE_AIO_H)
        /* POSIX aio */
        struct event rtsigs[SIGRTMAX - SIGRTMIN];
@@ -190,7 +192,7 @@ rspamd_eventfdcb (gint fd, gshort what, gpointer ud)
        struct aio_context                                      *ctx = ud;
        guint64                                                          ready;
        gint                                                             done, i;
-       struct io_event                                          event[64];
+       struct io_event                                          event[32];
        struct timespec                                          ts;
        struct io_cbdata                                        *ev_data;
 
@@ -207,7 +209,7 @@ rspamd_eventfdcb (gint fd, gshort what, gpointer ud)
 
        while (ready) {
                /* Get events ready */
-               done = io_getevents (ctx->io_ctx, 1, 64, event, &ts);
+               done = io_getevents (ctx->io_ctx, 1, 32, event, &ts);
 
                if (done > 0) {
                        ready -= done;
@@ -288,11 +290,11 @@ rspamd_aio_open (struct aio_context *ctx, const gchar *path, int flags)
        }
 #ifdef LINUX
 
-       fd = open (path, flags | O_DIRECT | O_NONBLOCK);
+       fd = open (path, flags | O_DIRECT);
 
        return fd;
 #elif defined(HAVE_AIO_H)
-       fd = open (path, flags | O_NONBLOCK);
+       fd = open (path, flags);
 #endif
 
        return fd;
@@ -376,6 +378,19 @@ rspamd_aio_write (gint fd, gpointer buf, gsize len, off_t offset, struct aio_con
 #ifdef LINUX
                struct iocb                                                              *iocb[1];
 
+               /* We need to align pointer on boundary of 512 bytes here */
+               if (ctx->buflen < len) {
+                       if (ctx->buf) {
+                               free (ctx->buf);
+                       }
+                       if (posix_memalign (&ctx->buf, 512, len) != 0) {
+                               return -1;
+                       }
+                       else {
+                               ctx->buflen = len;
+                               memcpy (ctx->buf, buf, len);
+                       }
+               }
                cbdata = g_slice_alloc (sizeof (struct io_cbdata));
                cbdata->cb = cb;
                cbdata->buf = buf;
@@ -388,7 +403,7 @@ rspamd_aio_write (gint fd, gpointer buf, gsize len, off_t offset, struct aio_con
                iocb[0]->aio_fildes = fd;
                iocb[0]->aio_lio_opcode = IO_CMD_PWRITE;
                iocb[0]->aio_reqprio = 0;
-               iocb[0]->aio_buf = (guint64)((uintptr_t)buf);
+               iocb[0]->aio_buf = (guint64)((uintptr_t)ctx->buf);
                iocb[0]->aio_nbytes = len;
                iocb[0]->aio_offset = offset;
                iocb[0]->aio_flags |= (1 << 0) /* IOCB_FLAG_RESFD */;
@@ -447,6 +462,9 @@ rspamd_aio_close (gint fd, struct aio_context *ctx)
 
                /* Iocb is copied to kernel internally, so it is safe to put it on stack */
                r = io_cancel (ctx->io_ctx, &iocb, &ev);
+               if (ctx->buf) {
+                       free (ctx->buf);
+               }
                close (fd);
                return r;
 
index f2c6e6421e15f21ef78e94464c7348acd534f079..2308acc671000eaaad8a31a7016c38c38e8b0cb3 100644 (file)
@@ -25,6 +25,7 @@
 #include "tests.h"
 #include "main.h"
 #include "aio_event.h"
+#include "mem_pool.h"
 
 
 extern struct event_base *base;
@@ -35,7 +36,7 @@ aio_read_cb (gint fd, gint res, gsize len, gpointer data, gpointer ud)
        guchar *p = data;
        guint i;
 
-       g_assert (res != -1);
+       g_assert (res > 0);
 
        g_assert (len == BUFSIZ);
        for (i = 0; i < len; i ++) {
@@ -49,11 +50,13 @@ static void
 aio_write_cb (gint fd, gint res, gsize len, gpointer data, gpointer ud)
 {
        struct aio_context *aio_ctx = ud;
-       static gchar testbuf[BUFSIZ];
+       gchar *testbuf;
+
+       g_assert (res > 0);
 
-       g_assert (res != -1);
+       g_assert (posix_memalign ((void **)&testbuf, 512, BUFSIZ) == 0);
 
-       g_assert (rspamd_aio_read (fd, testbuf, sizeof (testbuf), aio_ctx, aio_read_cb, aio_ctx) != -1);
+       g_assert (rspamd_aio_read (fd, testbuf, BUFSIZ, 0, aio_ctx, aio_read_cb, aio_ctx) != -1);
 }
 
 void
@@ -76,7 +79,7 @@ rspamd_async_test_func ()
 
        /* Write some data */
        memset (testbuf, 0xef, sizeof (testbuf));
-       ret = rspamd_aio_write (afd, testbuf, sizeof (testbuf), aio_ctx, aio_write_cb, aio_ctx);
+       ret = rspamd_aio_write (afd, testbuf, sizeof (testbuf), 0, aio_ctx, aio_write_cb, aio_ctx);
        g_assert (ret != -1);
 
        event_base_loop (base, 0);