summaryrefslogtreecommitdiff
path: root/accel-pppd/triton
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2014-05-12 13:50:15 +0400
committerDmitry Kozlov <xeb@mail.ru>2014-05-12 13:50:15 +0400
commit0c0bdd363b63319c7484f5cfbe6dd74a15b884be (patch)
tree1e5e4f596347cd80a57af5ca68b37eb27fcd91d5 /accel-pppd/triton
parent7466e7f10fb4813a6112682dff13de5fbdd981a7 (diff)
downloadaccel-ppp-0c0bdd363b63319c7484f5cfbe6dd74a15b884be.tar.gz
accel-ppp-0c0bdd363b63319c7484f5cfbe6dd74a15b884be.zip
triton: improved epoll events handling
Diffstat (limited to 'accel-pppd/triton')
-rw-r--r--accel-pppd/triton/md.c49
-rw-r--r--accel-pppd/triton/triton.c22
-rw-r--r--accel-pppd/triton/triton.h2
-rw-r--r--accel-pppd/triton/triton_p.h1
4 files changed, 53 insertions, 21 deletions
diff --git a/accel-pppd/triton/md.c b/accel-pppd/triton/md.c
index c9ec32e..a7eb5c8 100644
--- a/accel-pppd/triton/md.c
+++ b/accel-pppd/triton/md.c
@@ -97,19 +97,22 @@ static void *md_thread(void *arg)
triton_thread_wakeup(h->ctx->thread);
}
- while (!list_empty(&freed_list2)) {
- h = list_entry(freed_list2.next, typeof(*h), entry);
- list_del(&h->entry);
- mempool_free(h);
- }
-
pthread_mutex_lock(&freed_list_lock);
while (!list_empty(&freed_list)) {
h = list_entry(freed_list.next, typeof(*h), entry);
- list_del(&h->entry);
- list_add(&h->entry, &freed_list2);
+ list_move(&h->entry, &freed_list2);
}
pthread_mutex_unlock(&freed_list_lock);
+
+ while (!list_empty(&freed_list2)) {
+ h = list_entry(freed_list2.next, typeof(*h), entry);
+ list_del(&h->entry);
+ if (h->fd != -1) {
+ r = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, h->fd, NULL);
+ close(h->fd);
+ }
+ mempool_free(h);
+ }
}
return NULL;
@@ -130,13 +133,22 @@ void __export triton_md_register_handler(struct triton_context_t *ctx, struct tr
list_add_tail(&h->entry, &h->ctx->handlers);
spin_unlock(&h->ctx->lock);
- triton_stat.md_handler_count++;
+ __sync_add_and_fetch(&triton_stat.md_handler_count, 1);
}
-void __export triton_md_unregister_handler(struct triton_md_handler_t *ud)
+
+void __export triton_md_unregister_handler(struct triton_md_handler_t *ud, int c)
{
struct _triton_md_handler_t *h = (struct _triton_md_handler_t *)ud->tpd;
triton_md_disable_handler(ud, MD_MODE_READ | MD_MODE_WRITE);
+ if (c) {
+ h->fd = ud->fd;
+ ud->fd = -1;
+ } else {
+ triton_md_disable_handler(ud, MD_MODE_READ | MD_MODE_WRITE);
+ h->fd = -1;
+ }
+
spin_lock(&h->ctx->lock);
h->ud = NULL;
list_del(&h->entry);
@@ -146,16 +158,15 @@ void __export triton_md_unregister_handler(struct triton_md_handler_t *ud)
}
spin_unlock(&h->ctx->lock);
- sched_yield();
-
pthread_mutex_lock(&freed_list_lock);
list_add_tail(&h->entry, &freed_list);
pthread_mutex_unlock(&freed_list_lock);
ud->tpd = NULL;
- triton_stat.md_handler_count--;
+ __sync_sub_and_fetch(&triton_stat.md_handler_count, 1);
}
+
int __export triton_md_enable_handler(struct triton_md_handler_t *ud, int mode)
{
struct _triton_md_handler_t *h = (struct _triton_md_handler_t *)ud->tpd;
@@ -170,6 +181,9 @@ int __export triton_md_enable_handler(struct triton_md_handler_t *ud, int mode)
if (!h->trig_level)
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
@@ -182,18 +196,23 @@ int __export triton_md_enable_handler(struct triton_md_handler_t *ud, int mode)
return r;
}
+
int __export triton_md_disable_handler(struct triton_md_handler_t *ud,int mode)
{
struct _triton_md_handler_t *h = (struct _triton_md_handler_t *)ud->tpd;
- int r=0;
+ int r = 0;
+ int events = h->epoll_event.events;
if (!h->epoll_event.events)
- return -1;
+ return 0;
if (mode & MD_MODE_READ)
h->epoll_event.events &= ~EPOLLIN;
if (mode & MD_MODE_WRITE)
h->epoll_event.events &= ~EPOLLOUT;
+
+ 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);
diff --git a/accel-pppd/triton/triton.c b/accel-pppd/triton/triton.c
index 8bde56d..ef9078b 100644
--- a/accel-pppd/triton/triton.c
+++ b/accel-pppd/triton/triton.c
@@ -183,6 +183,7 @@ static void ctx_thread(struct _triton_context_t *ctx)
struct _triton_timer_t *t;
struct _triton_ctx_call_t *call;
uint64_t tt;
+ int events;
log_debug2("ctx %p %p: enter\n", ctx, ctx->thread);
@@ -199,23 +200,33 @@ static void ctx_thread(struct _triton_context_t *ctx)
t->ud->expire(t->ud);
continue;
}
+
if (!list_empty(&ctx->pending_handlers)) {
h = list_entry(ctx->pending_handlers.next, typeof(*h), entry2);
list_del(&h->entry2);
h->pending = 0;
+ events = h->trig_epoll_events;
spin_unlock(&ctx->lock);
+
__sync_sub_and_fetch(&triton_stat.md_handler_pending, 1);
- if (h->trig_epoll_events & (EPOLLIN | EPOLLERR | EPOLLHUP))
- if (h->ud && h->ud->read)
+
+ if ((events & (EPOLLIN | EPOLLERR | EPOLLHUP)) && (h->epoll_event.events & EPOLLIN)) {
+ if (h->ud && h->ud->read) {
if (h->ud->read(h->ud))
continue;
- if (h->trig_epoll_events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
- if (h->ud && h->ud->write)
+ }
+ }
+
+ if ((events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) && (h->epoll_event.events & EPOLLOUT)) {
+ if (h->ud && h->ud->write) {
if (h->ud->write(h->ud))
continue;
- h->trig_epoll_events = 0;
+ }
+ }
+
continue;
}
+
if (!list_empty(&ctx->pending_calls)) {
call = list_entry(ctx->pending_calls.next, typeof(*call), entry);
list_del(&call->entry);
@@ -224,6 +235,7 @@ static void ctx_thread(struct _triton_context_t *ctx)
mempool_free(call);
continue;
}
+
ctx->pending = 0;
spin_unlock(&ctx->lock);
break;
diff --git a/accel-pppd/triton/triton.h b/accel-pppd/triton/triton.h
index e47eb36..71bb174 100644
--- a/accel-pppd/triton/triton.h
+++ b/accel-pppd/triton/triton.h
@@ -85,7 +85,7 @@ struct triton_context_t *triton_context_self(void);
#define MD_TRIG_LEVEL 1
void triton_md_register_handler(struct triton_context_t *, struct triton_md_handler_t *);
-void triton_md_unregister_handler(struct triton_md_handler_t *h);
+void triton_md_unregister_handler(struct triton_md_handler_t *h, int close);
int triton_md_enable_handler(struct triton_md_handler_t *h, int mode);
int triton_md_disable_handler(struct triton_md_handler_t *h,int mode);
void triton_md_set_trig(struct triton_md_handler_t *h, int mode);
diff --git a/accel-pppd/triton/triton_p.h b/accel-pppd/triton/triton_p.h
index 443cede..d86f1bc 100644
--- a/accel-pppd/triton/triton_p.h
+++ b/accel-pppd/triton/triton_p.h
@@ -53,6 +53,7 @@ struct _triton_md_handler_t
struct _triton_context_t *ctx;
struct epoll_event epoll_event;
uint32_t trig_epoll_events;
+ int fd;
int pending:1;
int trig_level:1;
struct triton_md_handler_t *ud;