aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2012-03-11 17:53:58 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2012-03-11 17:53:58 +0400
commit7437cc1df6e16a884678f8725957cbcd9843fc33 (patch)
tree8e0744ff3b08a62b18c232c9b1148a11c4861767
parent899c90dd4273245f3e26cb2d2cf311918dcc9068 (diff)
downloadrspamd-7437cc1df6e16a884678f8725957cbcd9843fc33.tar.gz
rspamd-7437cc1df6e16a884678f8725957cbcd9843fc33.zip
Aio context must be long not int.
O_DIRECT on linux requires strict memory alignment.
-rw-r--r--src/aio_event.c36
-rw-r--r--test/rspamd_async_test.c13
2 files changed, 35 insertions, 14 deletions
diff --git a/src/aio_event.c b/src/aio_event.c
index dc1d8284a..9dd0df35a 100644
--- a/src/aio_event.c
+++ b/src/aio_event.c
@@ -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;
diff --git a/test/rspamd_async_test.c b/test/rspamd_async_test.c
index f2c6e6421..2308acc67 100644
--- a/test/rspamd_async_test.c
+++ b/test/rspamd_async_test.c
@@ -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);