[dovecot-cvs] dovecot/src/lib Makefile.am, 1.51,
1.52 ioloop-internal.h, 1.12, 1.13 ioloop-notify-dn.c, 1.3,
1.4 ioloop-notify-inotify.c, NONE, 1.1 ioloop-notify-none.c,
1.2, 1.3 ioloop.c, 1.25, 1.26
cras at dovecot.org
cras at dovecot.org
Tue Jul 12 18:40:36 EEST 2005
- Previous message: [dovecot-cvs] dovecot/src/lib-imap imap-parser.c, 1.49,
1.50 imap-parser.h, 1.15, 1.16
- Next message: [dovecot-cvs] dovecot/src/lib ioloop-epoll.c, 1.3,
1.4 ioloop-internal.h, 1.13, 1.14 ioloop-poll.c, 1.25,
1.26 ioloop-select.c, 1.19, 1.20
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /var/lib/cvs/dovecot/src/lib
In directory talvi:/tmp/cvs-serv2271/src/lib
Modified Files:
Makefile.am ioloop-internal.h ioloop-notify-dn.c
ioloop-notify-none.c ioloop.c
Added Files:
ioloop-notify-inotify.c
Log Message:
Added inotify patch by Johannes Berg and did some restructuring to
ioloop notify internals.
Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/Makefile.am,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- Makefile.am 12 Jul 2005 13:07:47 -0000 1.51
+++ Makefile.am 12 Jul 2005 15:40:33 -0000 1.52
@@ -29,6 +29,7 @@
ioloop.c \
ioloop-notify-none.c \
ioloop-notify-dn.c \
+ ioloop-notify-inotify.c \
ioloop-poll.c \
ioloop-select.c \
ioloop-epoll.c \
Index: ioloop-internal.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop-internal.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- ioloop-internal.h 25 Aug 2004 12:27:44 -0000 1.12
+++ ioloop-internal.h 12 Jul 2005 15:40:33 -0000 1.13
@@ -9,11 +9,12 @@
pool_t pool;
struct io *ios;
- struct io *notifys, *event_io;
+ struct io *notifys;
struct io *next_io;
struct timeout *timeouts; /* sorted by next_run */
struct ioloop_handler_data *handler_data;
+ struct ioloop_notify_handler_context *notify_handler_context;
unsigned int running:1;
};
@@ -26,6 +27,8 @@
io_callback_t *callback;
void *context;
+
+ int notify_context;
};
struct timeout {
@@ -55,6 +58,9 @@
void io_loop_handler_init(struct ioloop *ioloop);
void io_loop_handler_deinit(struct ioloop *ioloop);
+void io_loop_notify_handler_init(struct ioloop *ioloop);
+void io_loop_notify_handler_deinit(struct ioloop *ioloop);
+
struct io *io_loop_notify_add(struct ioloop *ioloop, int fd,
enum io_condition condition,
io_callback_t *callback, void *context);
Index: ioloop-notify-dn.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop-notify-dn.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- ioloop-notify-dn.c 5 Sep 2004 22:06:26 -0000 1.3
+++ ioloop-notify-dn.c 12 Jul 2005 15:40:33 -0000 1.4
@@ -14,6 +14,10 @@
#include <unistd.h>
#include <fcntl.h>
+struct ioloop_notify_handler_context {
+ struct io *event_io;
+};
+
static int event_pipe[2] = { -1, -1 };
static void sigrt_handler(int signo __attr_unused__, siginfo_t *si,
@@ -52,50 +56,19 @@
}
}
-static int dn_init(void)
-{
- struct sigaction act;
-
- if (pipe(event_pipe) < 0) {
- i_error("pipe() failed: %m");
- return FALSE;
- }
-
- net_set_nonblock(event_pipe[0], TRUE);
- net_set_nonblock(event_pipe[1], TRUE);
-
- /* SIGIO is sent if queue gets full. we'll just ignore it. */
- signal(SIGIO, SIG_IGN);
-
- act.sa_sigaction = sigrt_handler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
-
- if (sigaction(SIGRTMIN, &act, NULL) < 0) {
- i_error("sigaction(SIGRTMIN) failed: %m");
- close(event_pipe[0]);
- close(event_pipe[1]);
- return FALSE;
- }
-
- return TRUE;
-}
-
struct io *io_loop_notify_add(struct ioloop *ioloop, int fd,
enum io_condition condition,
io_callback_t *callback, void *context)
{
+ struct ioloop_notify_handler_context *ctx =
+ ioloop->notify_handler_context;
struct io *io;
if ((condition & IO_FILE_NOTIFY) != 0)
return NULL;
- if (event_pipe[0] == -1) {
- if (!dn_init())
- return NULL;
- }
- if (ioloop->event_io == NULL) {
- ioloop->event_io =
+ if (ctx->event_io == NULL) {
+ ctx->event_io =
io_add(event_pipe[0], IO_READ, event_callback, ioloop);
}
@@ -124,6 +97,8 @@
void io_loop_notify_remove(struct ioloop *ioloop, struct io *io)
{
+ struct ioloop_notify_handler_context *ctx =
+ ioloop->notify_handler_context;
struct io **io_p;
for (io_p = &ioloop->notifys; *io_p != NULL; io_p = &(*io_p)->next) {
@@ -141,9 +116,53 @@
p_free(ioloop->pool, io);
if (ioloop->notifys == NULL) {
- io_remove(ioloop->event_io);
- ioloop->event_io = NULL;
+ io_remove(ctx->event_io);
+ ctx->event_io = NULL;
}
}
+void io_loop_notify_handler_init(struct ioloop *ioloop)
+{
+ struct ioloop_notify_handler_context *ctx;
+ struct sigaction act;
+
+ i_assert(event_pipe[0] == -1);
+
+ ctx = ioloop->notify_handler_context =
+ i_new(struct ioloop_notify_handler_context, 1);
+
+ if (pipe(event_pipe) < 0) {
+ i_fatal("pipe() failed: %m");
+ return;
+ }
+
+ net_set_nonblock(event_pipe[0], TRUE);
+ net_set_nonblock(event_pipe[1], TRUE);
+
+ /* SIGIO is sent if queue gets full. we'll just ignore it. */
+ signal(SIGIO, SIG_IGN);
+
+ act.sa_sigaction = sigrt_handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
+
+ if (sigaction(SIGRTMIN, &act, NULL) < 0)
+ i_fatal("sigaction(SIGRTMIN) failed: %m");
+}
+
+void io_loop_notify_handler_deinit(struct ioloop *ioloop __attr_unused__)
+{
+ struct ioloop_notify_handler_context *ctx =
+ ioloop->notify_handler_context;
+
+ signal(SIGRTMIN, SIG_IGN);
+
+ if (close(event_pipe[0]) < 0)
+ i_error("close(event_pipe[0]) failed: %m");
+ if (close(event_pipe[1]) < 0)
+ i_error("close(event_pipe[1]) failed: %m");
+
+ i_free(ctx);
+}
+
#endif
--- NEW FILE: ioloop-notify-inotify.c ---
/* Copyright (C) 2005 Johannes Berg */
#define _GNU_SOURCE
#include "lib.h"
#ifdef IOLOOP_NOTIFY_INOTIFY
#include "ioloop-internal.h"
#include "buffer.h"
#include "network.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/inotify.h>
#define INITIAL_INOTIFY_BUFLEN (FILENAME_MAX + sizeof(struct inotify_event))
#define MAXIMAL_INOTIFY_BUFLEN (32*1024)
struct ioloop_notify_handler_context {
int inotify_fd;
struct io *event_io;
buffer_t *buf;
};
static int event_read_next(struct ioloop *ioloop)
{
struct ioloop_notify_handler_context *ctx =
ioloop->notify_handler_context;
struct io *io;
struct inotify_event *event;
ssize_t ret;
size_t record_length;
int required_bytes;
if (ioctl(ctx->inotify_fd, FIONREAD, &required_bytes))
i_fatal("ioctl(inotify_fd, FIONREAD) failed: %m");
if (required_bytes <= 0)
return FALSE;
if (required_bytes > MAXIMAL_INOTIFY_BUFLEN)
required_bytes = MAXIMAL_INOTIFY_BUFLEN;
event = buffer_get_space_unsafe(ctx->buf, 0, required_bytes);
ret = read(ctx->inotify_fd, (void *)event, required_bytes);
if (ret == 0)
return FALSE;
if (ret < 0)
i_fatal("read(inotify_fd) failed: %m");
if (gettimeofday(&ioloop_timeval, &ioloop_timezone) < 0)
i_fatal("gettimeofday(): %m");
ioloop_time = ioloop_timeval.tv_sec;
while ((size_t)required_bytes > sizeof(*event)) {
for (io = ioloop->notifys; io != NULL; io = io->next) {
if (io->notify_context == event->wd) {
io->callback(io->context);
break;
}
}
record_length = event->len + sizeof(struct inotify_event);
if ((size_t)required_bytes < record_length)
break;
required_bytes -= record_length;
/* this might point outside the area if the loop
won't run again */
event = PTR_OFFSET(event, record_length);
}
return TRUE;
}
static void event_callback(void *context)
{
struct ioloop *ioloop = context;
while (event_read_next(ioloop)) ;
}
struct io *io_loop_notify_add(struct ioloop *ioloop, int fd,
enum io_condition condition,
io_callback_t *callback, void *context)
{
struct ioloop_notify_handler_context *ctx =
ioloop->notify_handler_context;
struct io *io;
struct inotify_watch_request req;
int added = FALSE;
int watchdescriptor;
if ((condition & IO_FILE_NOTIFY) != 0)
return NULL;
if (ctx->event_io == NULL) {
added = TRUE;
ctx->event_io = io_add(ctx->inotify_fd, IO_READ,
event_callback, ioloop);
}
/* now set up the notification request and shoot it off */
req.fd = fd;
req.mask = IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE | IN_MODIFY;
watchdescriptor = ioctl(ctx->inotify_fd, INOTIFY_WATCH, &req);
if (watchdescriptor < 0) {
i_error("ioctl(INOTIFY_WATCH) failed: %m");
if (added) {
io_remove(ctx->event_io);
ctx->event_io = NULL;
}
return NULL;
}
io = p_new(ioloop->pool, struct io, 1);
io->fd = fd;
io->condition = condition;
io->callback = callback;
io->context = context;
io->notify_context = watchdescriptor;
io->next = ioloop->notifys;
ioloop->notifys = io;
return io;
}
void io_loop_notify_remove(struct ioloop *ioloop, struct io *io)
{
struct ioloop_notify_handler_context *ctx =
ioloop->notify_handler_context;
struct io **io_p;
for (io_p = &ioloop->notifys; *io_p != NULL; io_p = &(*io_p)->next) {
if (*io_p == io) {
*io_p = io->next;
break;
}
}
if (ioctl(ctx->inotify_fd, INOTIFY_IGNORE, &io->notify_context) < 0)
i_error("ioctl(INOTIFY_IGNORE) failed: %m");
p_free(ioloop->pool, io);
if (ioloop->notifys == NULL) {
io_remove(ctx->event_io);
ctx->event_io = NULL;
}
}
void io_loop_notify_handler_init(struct ioloop *ioloop)
{
struct ioloop_notify_handler_context *ctx;
ctx = ioloop->notify_handler_context =
i_new(struct ioloop_notify_handler_context, 1);
ctx->inotify_fd = open("/dev/inotify", O_RDONLY);
if (ctx->inotify_fd < 0)
i_fatal("open(/dev/inotify) failed: %m");
ctx->buf = buffer_create_dynamic(default_pool, INITIAL_INOTIFY_BUFLEN);
}
void io_loop_notify_handler_deinit(struct ioloop *ioloop)
{
struct ioloop_notify_handler_context *ctx =
ioloop->notify_handler_context;
if (close(ctx->inotify_fd) < 0)
i_error("close(/dev/inotify) failed: %m");
buffer_free(ctx->buf);
i_free(ctx);
}
#endif
Index: ioloop-notify-none.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop-notify-none.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ioloop-notify-none.c 21 Oct 2004 02:27:12 -0000 1.2
+++ ioloop-notify-none.c 12 Jul 2005 15:40:33 -0000 1.3
@@ -19,4 +19,12 @@
{
}
+void io_loop_notify_handler_init(struct ioloop *ioloop __attr_unused__)
+{
+}
+
+void io_loop_notify_handler_deinit(struct ioloop *ioloop __attr_unused__)
+{
+}
+
#endif
Index: ioloop.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ioloop.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- ioloop.c 25 Aug 2004 12:27:44 -0000 1.25
+++ ioloop.c 12 Jul 2005 15:40:33 -0000 1.26
@@ -247,6 +247,7 @@
ioloop->pool = pool;
io_loop_handler_init(ioloop);
+ io_loop_notify_handler_init(ioloop);
ioloop->prev = current_ioloop;
current_ioloop = ioloop;
@@ -275,6 +276,7 @@
timeout_destroy(ioloop, &ioloop->timeouts);
}
+ io_loop_notify_handler_deinit(ioloop);
io_loop_handler_deinit(ioloop);
/* ->prev won't work unless loops are destroyed in create order */
- Previous message: [dovecot-cvs] dovecot/src/lib-imap imap-parser.c, 1.49,
1.50 imap-parser.h, 1.15, 1.16
- Next message: [dovecot-cvs] dovecot/src/lib ioloop-epoll.c, 1.3,
1.4 ioloop-internal.h, 1.13, 1.14 ioloop-poll.c, 1.25,
1.26 ioloop-select.c, 1.19, 1.20
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list