summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2012-05-19 12:15:51 +0200
committerDavid Herrmann <dh.herrmann@googlemail.com>2012-05-19 12:15:51 +0200
commit9703ee3502301c8358ff4da4937af86e6f66235e (patch)
tree00b8d7d2768377b37e28102fd32baed376a4492f
parent3ca31d922b0fe3b4b42c5dcb943fdb6520cd0375 (diff)
eloop: correctly forward error codes
Instead of ignoring epoll errors we should forward them to the caller. The caller can then still decide to ignore errors. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
-rw-r--r--src/eloop.c101
-rw-r--r--src/eloop.h8
2 files changed, 78 insertions, 31 deletions
diff --git a/src/eloop.c b/src/eloop.c
index 3bfc4d0..3073d27 100644
--- a/src/eloop.c
+++ b/src/eloop.c
@@ -1,7 +1,7 @@
/*
* Event Loop
*
- * Copyright (c) 2011 David Herrmann <dh.herrmann@googlemail.com>
+ * Copyright (c) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
* Copyright (c) 2011 University of Tuebingen
*
* Permission is hereby granted, free of charge, to any person obtaining
@@ -529,13 +529,13 @@ void ev_fd_unref(struct ev_fd *fd)
free(fd);
}
-static void fd_epoll_add(struct ev_fd *fd)
+static int fd_epoll_add(struct ev_fd *fd)
{
struct epoll_event ep;
int ret;
if (!fd->loop)
- return;
+ return 0;
memset(&ep, 0, sizeof(ep));
if (fd->mask & EV_READABLE)
@@ -545,9 +545,13 @@ static void fd_epoll_add(struct ev_fd *fd)
ep.data.ptr = fd;
ret = epoll_ctl(fd->loop->efd, EPOLL_CTL_ADD, fd->fd, &ep);
- if (ret)
+ if (ret) {
log_warning("cannot add fd %d to epoll set (%d): %m",
fd->fd, errno);
+ return -EFAULT;
+ }
+
+ return 0;
}
static void fd_epoll_remove(struct ev_fd *fd)
@@ -563,13 +567,13 @@ static void fd_epoll_remove(struct ev_fd *fd)
fd->fd, errno);
}
-static void fd_epoll_update(struct ev_fd *fd)
+static int fd_epoll_update(struct ev_fd *fd)
{
struct epoll_event ep;
int ret;
if (!fd->loop)
- return;
+ return 0;
memset(&ep, 0, sizeof(ep));
if (fd->mask & EV_READABLE)
@@ -579,18 +583,30 @@ static void fd_epoll_update(struct ev_fd *fd)
ep.data.ptr = fd;
ret = epoll_ctl(fd->loop->efd, EPOLL_CTL_MOD, fd->fd, &ep);
- if (ret)
+ if (ret) {
log_warning("cannot update epoll fd %d (%d): %m",
fd->fd, errno);
+ return -EFAULT;
+ }
+
+ return 0;
}
-void ev_fd_enable(struct ev_fd *fd)
+int ev_fd_enable(struct ev_fd *fd)
{
- if (!fd || fd->enabled)
- return;
+ int ret;
+
+ if (!fd)
+ return -EINVAL;
+ if (fd->enabled)
+ return 0;
+
+ ret = fd_epoll_add(fd);
+ if (ret)
+ return ret;
fd->enabled = true;
- fd_epoll_add(fd);
+ return 0;
}
void ev_fd_disable(struct ev_fd *fd)
@@ -621,15 +637,27 @@ void ev_fd_set_cb_data(struct ev_fd *fd, ev_fd_cb cb, void *data)
fd->data = data;
}
-void ev_fd_update(struct ev_fd *fd, int mask)
+int ev_fd_update(struct ev_fd *fd, int mask)
{
+ int ret;
+ int omask;
+
if (!fd)
- return;
+ return -EINVAL;
+ omask = fd->mask;
fd->mask = mask;
+
if (!fd->enabled)
- return;
- fd_epoll_update(fd);
+ return 0;
+
+ ret = fd_epoll_update(fd);
+ if (ret) {
+ fd->mask = omask;
+ return ret;
+ }
+
+ return 0;
}
int ev_eloop_new_fd(struct ev_eloop *loop, struct ev_fd **out, int rfd,
@@ -645,25 +673,36 @@ int ev_eloop_new_fd(struct ev_eloop *loop, struct ev_fd **out, int rfd,
if (ret)
return ret;
- ev_eloop_add_fd(loop, fd);
- ev_fd_unref(fd);
+ ret = ev_eloop_add_fd(loop, fd);
+ if (ret) {
+ ev_fd_unref(fd);
+ return ret;
+ }
+ ev_fd_unref(fd);
*out = fd;
return 0;
}
int ev_eloop_add_fd(struct ev_eloop *loop, struct ev_fd *fd)
{
+ int ret;
+
if (!loop || !fd || fd->loop)
return -EINVAL;
fd->loop = loop;
- ev_fd_ref(fd);
- ev_eloop_ref(loop);
- if (fd->enabled)
- fd_epoll_add(fd);
+ if (fd->enabled) {
+ ret = fd_epoll_add(fd);
+ if (ret) {
+ fd->loop = NULL;
+ return ret;
+ }
+ }
+ ev_fd_ref(fd);
+ ev_eloop_ref(loop);
return 0;
}
@@ -810,16 +849,20 @@ void ev_timer_set_cb_data(struct ev_timer *timer, ev_timer_cb cb, void *data)
timer->data = data;
}
-void ev_timer_update(struct ev_timer *timer, const struct itimerspec *spec)
+int ev_timer_update(struct ev_timer *timer, const struct itimerspec *spec)
{
int ret;
if (!timer || !spec)
- return;
+ return -EINVAL;
ret = timerfd_settime(timer->fd, 0, spec, NULL);
- if (ret)
+ if (ret) {
log_warn("cannot set timerfd (%d): %m", errno);
+ return -EFAULT;
+ }
+
+ return 0;
}
int ev_eloop_new_timer(struct ev_eloop *loop, struct ev_timer **out,
@@ -985,16 +1028,16 @@ void ev_counter_set_cb_data(struct ev_counter *cnt, ev_counter_cb cb,
cnt->data = data;
}
-void ev_counter_inc(struct ev_counter *cnt, uint64_t val)
+int ev_counter_inc(struct ev_counter *cnt, uint64_t val)
{
int ret;
if (!cnt || !val)
- return;
+ return -EINVAL;
if (val == 0xffffffffffffffffULL) {
log_warning("increasing counter with invalid value %llu", val);
- return;
+ return -EINVAL;;
}
ret = write(cnt->fd, &val, sizeof(val));
@@ -1003,9 +1046,13 @@ void ev_counter_inc(struct ev_counter *cnt, uint64_t val)
log_warning("eventfd overflow while writing %llu", val);
else
log_warning("eventfd write error (%d): %m", errno);
+ return -EFAULT;
} else if (ret != sizeof(val)) {
log_warning("wrote %d bytes instead of 8 to eventdfd", ret);
+ return -EFAULT;
}
+
+ return 0;
}
int ev_eloop_new_counter(struct ev_eloop *eloop, struct ev_counter **out,
diff --git a/src/eloop.h b/src/eloop.h
index 221761b..faea978 100644
--- a/src/eloop.h
+++ b/src/eloop.h
@@ -82,12 +82,12 @@ int ev_fd_new(struct ev_fd **out, int fd, int mask, ev_fd_cb cb, void *data);
void ev_fd_ref(struct ev_fd *fd);
void ev_fd_unref(struct ev_fd *fd);
-void ev_fd_enable(struct ev_fd *fd);
+int ev_fd_enable(struct ev_fd *fd);
void ev_fd_disable(struct ev_fd *fd);
bool ev_fd_is_enabled(struct ev_fd *fd);
bool ev_fd_is_bound(struct ev_fd *fd);
void ev_fd_set_cb_data(struct ev_fd *fd, ev_fd_cb cb, void *data);
-void ev_fd_update(struct ev_fd *fd, int mask);
+int ev_fd_update(struct ev_fd *fd, int mask);
int ev_eloop_new_fd(struct ev_eloop *loop, struct ev_fd **out, int rfd,
int mask, ev_fd_cb cb, void *data);
@@ -103,7 +103,7 @@ void ev_timer_unref(struct ev_timer *timer);
bool ev_timer_is_bound(struct ev_timer *timer);
void ev_timer_set_cb_data(struct ev_timer *timer, ev_timer_cb cb, void *data);
-void ev_timer_update(struct ev_timer *timer, const struct itimerspec *spec);
+int ev_timer_update(struct ev_timer *timer, const struct itimerspec *spec);
int ev_eloop_new_timer(struct ev_eloop *loop, struct ev_timer **out,
const struct itimerspec *spec, ev_timer_cb cb,
@@ -120,7 +120,7 @@ void ev_counter_unref(struct ev_counter *cnt);
bool ev_counter_is_bound(struct ev_counter *cnt);
void ev_counter_set_cb_data(struct ev_counter *cnt, ev_counter_cb cb,
void *data);
-void ev_counter_inc(struct ev_counter *cnt, uint64_t val);
+int ev_counter_inc(struct ev_counter *cnt, uint64_t val);
int ev_eloop_new_counter(struct ev_eloop *eloop, struct ev_counter **out,
ev_counter_cb cb, void *data);