summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2014-09-22 21:48:17 +0400
committerDmitry Kozlov <xeb@mail.ru>2014-09-22 21:48:17 +0400
commitd36fc2b235ddaaa3fbb84a46ef520a0a207293df (patch)
tree075126d1a4a0e133dde1ff55e6403334799c0202
parent731682bcb429470d366903adf7056151a94816b7 (diff)
downloadaccel-ppp-d36fc2b235ddaaa3fbb84a46ef520a0a207293df.tar.gz
accel-ppp-d36fc2b235ddaaa3fbb84a46ef520a0a207293df.zip
triton: make level triggered events oneshot (EPOLLONESHOT)
-rw-r--r--accel-pppd/triton/md.c44
-rw-r--r--accel-pppd/triton/timer.c2
-rw-r--r--accel-pppd/triton/triton.c6
-rw-r--r--accel-pppd/triton/triton_p.h5
4 files changed, 47 insertions, 10 deletions
diff --git a/accel-pppd/triton/md.c b/accel-pppd/triton/md.c
index 1396d3ec..6067ff2e 100644
--- a/accel-pppd/triton/md.c
+++ b/accel-pppd/triton/md.c
@@ -5,6 +5,7 @@
#include <string.h>
#include <errno.h>
#include <unistd.h>
+#include <fcntl.h>
#include "triton_p.h"
@@ -32,6 +33,8 @@ int md_init(void)
return -1;
}
+ fcntl(epoll_fd, F_SETFD, O_CLOEXEC);
+
epoll_events = _malloc(max_events * sizeof(struct epoll_event));
if (!epoll_events) {
fprintf(stderr,"md:cann't allocate memory\n");
@@ -171,15 +174,22 @@ int __export triton_md_enable_handler(struct triton_md_handler_t *ud, int mode)
if (mode & MD_MODE_WRITE)
h->epoll_event.events |= EPOLLOUT;
- if (!h->trig_level)
+ if (h->trig_level)
+ h->epoll_event.events |= EPOLLONESHOT;
+ else
h->epoll_event.events |= EPOLLET;
if (events == h->epoll_event.events)
return 0;
- if (events)
- r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event);
- else
+ if (events) {
+ if (h->armed)
+ r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event);
+ else {
+ h->mod = 1;
+ r = 0;
+ }
+ } else
r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, h->ud->fd, &h->epoll_event);
if (r) {
@@ -204,13 +214,21 @@ int __export triton_md_disable_handler(struct triton_md_handler_t *ud,int mode)
if (mode & MD_MODE_WRITE)
h->epoll_event.events &= ~EPOLLOUT;
+ if (!(h->epoll_event.events & (EPOLLIN | EPOLLOUT)))
+ h->epoll_event.events = 0;
+
if (events == h->epoll_event.events)
return 0;
- if (h->epoll_event.events & (EPOLLIN | EPOLLOUT))
- r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event);
- else {
- h->epoll_event.events = 0;
+ if (h->epoll_event.events) {
+ if (h->armed)
+ r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event);
+ else {
+ h->mod = 1;
+ r = 0;
+ }
+ } else {
+ h->mod = 0;
r = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, h->ud->fd, NULL);
}
@@ -228,3 +246,13 @@ void __export triton_md_set_trig(struct triton_md_handler_t *ud, int mode)
h->trig_level = mode;
}
+void md_rearm(struct _triton_md_handler_t *h)
+{
+ if (h->mod) {
+ epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event);
+ h->mod = 0;
+ }
+
+ h->armed = 1;
+}
+
diff --git a/accel-pppd/triton/timer.c b/accel-pppd/triton/timer.c
index d0ebcb40..1e4f0612 100644
--- a/accel-pppd/triton/timer.c
+++ b/accel-pppd/triton/timer.c
@@ -39,6 +39,8 @@ int timer_init(void)
return -1;
}
+ fcntl(epoll_fd, F_SETFD, O_CLOEXEC);
+
epoll_events = _malloc(max_events * sizeof(struct epoll_event));
if (!epoll_events) {
fprintf(stderr,"timer: cannot allocate memory\n");
diff --git a/accel-pppd/triton/triton.c b/accel-pppd/triton/triton.c
index 5d6f31d1..f550db26 100644
--- a/accel-pppd/triton/triton.c
+++ b/accel-pppd/triton/triton.c
@@ -207,9 +207,11 @@ static void ctx_thread(struct _triton_context_t *ctx)
h->pending = 0;
events = h->trig_epoll_events;
spin_unlock(&ctx->lock);
-
+
__sync_sub_and_fetch(&triton_stat.md_handler_pending, 1);
+ h->armed = 0;
+
if ((events & (EPOLLIN | EPOLLERR | EPOLLHUP)) && (h->epoll_event.events & EPOLLIN)) {
if (h->ud && h->ud->read) {
if (h->ud->read(h->ud))
@@ -224,6 +226,8 @@ static void ctx_thread(struct _triton_context_t *ctx)
}
}
+ md_rearm(h);
+
continue;
}
diff --git a/accel-pppd/triton/triton_p.h b/accel-pppd/triton/triton_p.h
index 94017293..2bbccbd1 100644
--- a/accel-pppd/triton/triton_p.h
+++ b/accel-pppd/triton/triton_p.h
@@ -54,8 +54,10 @@ struct _triton_md_handler_t
struct _triton_context_t *ctx;
struct epoll_event epoll_event;
uint32_t trig_epoll_events;
- int pending:1;
+ int pending;
int trig_level:1;
+ int armed:1;
+ int mod:1;
struct triton_md_handler_t *ud;
};
@@ -98,6 +100,7 @@ int event_init();
void md_run();
void md_terminate();
+void md_rearm(struct _triton_md_handler_t *h);
void timer_run();
void timer_terminate();
extern struct triton_context_t default_ctx;