summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2014-05-18 21:21:19 +0000
committerDmitry Kozlov <xeb@mail.ru>2014-07-11 14:57:57 +0400
commitf7b2b5c9c05831e6f5ba4af1d03524980aee1f52 (patch)
treedf17a02f54a3f9a6766ac4213d70ce48107ebe0f
parent34751881be05d546f04dea2515e5b0d2617bff7c (diff)
downloadaccel-ppp-f7b2b5c9c05831e6f5ba4af1d03524980aee1f52.tar.gz
accel-ppp-f7b2b5c9c05831e6f5ba4af1d03524980aee1f52.zip
triton: fix possible race
-rw-r--r--accel-pppd/triton/md.c2
-rw-r--r--accel-pppd/triton/timer.c8
-rw-r--r--accel-pppd/triton/triton.c9
-rw-r--r--accel-pppd/triton/triton_p.h2
4 files changed, 15 insertions, 6 deletions
diff --git a/accel-pppd/triton/md.c b/accel-pppd/triton/md.c
index c9ec32e6..c97be452 100644
--- a/accel-pppd/triton/md.c
+++ b/accel-pppd/triton/md.c
@@ -100,6 +100,7 @@ static void *md_thread(void *arg)
while (!list_empty(&freed_list2)) {
h = list_entry(freed_list2.next, typeof(*h), entry);
list_del(&h->entry);
+ triton_context_release(h->ctx);
mempool_free(h);
}
@@ -125,6 +126,7 @@ void __export triton_md_register_handler(struct triton_context_t *ctx, struct tr
h->ctx = (struct _triton_context_t *)ctx->tpd;
else
h->ctx = (struct _triton_context_t *)default_ctx.tpd;
+ __sync_add_and_fetch(&h->ctx->refs, 1);
ud->tpd = h;
spin_lock(&h->ctx->lock);
list_add_tail(&h->entry, &h->ctx->handlers);
diff --git a/accel-pppd/triton/timer.c b/accel-pppd/triton/timer.c
index e5ebeb5c..d0ebcb40 100644
--- a/accel-pppd/triton/timer.c
+++ b/accel-pppd/triton/timer.c
@@ -107,15 +107,12 @@ void *timer_thread(void *arg)
while (!list_empty(&freed_list2)) {
t = list_entry(freed_list2.next, typeof(*t), entry);
list_del(&t->entry);
+ triton_context_release(t->ctx);
mempool_free(t);
}
pthread_mutex_lock(&freed_list_lock);
- while (!list_empty(&freed_list)) {
- t = list_entry(freed_list.next, typeof(*t), entry);
- list_del(&t->entry);
- list_add(&t->entry, &freed_list2);
- }
+ list_splice_init(&freed_list, &freed_list2);
pthread_mutex_unlock(&freed_list_lock);
}
@@ -147,6 +144,7 @@ int __export triton_timer_add(struct triton_context_t *ctx, struct triton_timer_
goto out_err;
}
+ __sync_add_and_fetch(&t->ctx->refs, 1);
ud->tpd = t;
if (triton_timer_mod(ud, abs_time))
diff --git a/accel-pppd/triton/triton.c b/accel-pppd/triton/triton.c
index f17ae316..667bb06a 100644
--- a/accel-pppd/triton/triton.c
+++ b/accel-pppd/triton/triton.c
@@ -169,7 +169,7 @@ cont:
if (thread->ctx->need_free) {
log_debug2("- context %p removed\n", thread->ctx);
- mempool_free(thread->ctx);
+ triton_context_release(thread->ctx);
}
thread->ctx = NULL;
@@ -296,6 +296,12 @@ int triton_queue_ctx(struct _triton_context_t *ctx)
return 1;
}
+void triton_context_release(struct _triton_context_t *ctx)
+{
+ if (__sync_sub_and_fetch(&ctx->refs, 1) == 0)
+ mempool_free(ctx);
+}
+
int __export triton_context_register(struct triton_context_t *ud, void *bf_arg)
{
struct _triton_context_t *ctx = mempool_alloc(ctx_pool);
@@ -308,6 +314,7 @@ int __export triton_context_register(struct triton_context_t *ud, void *bf_arg)
ctx->ud = ud;
ctx->bf_arg = bf_arg;
ctx->init = 1;
+ ctx->refs = 1;
spinlock_init(&ctx->lock);
INIT_LIST_HEAD(&ctx->handlers);
INIT_LIST_HEAD(&ctx->timers);
diff --git a/accel-pppd/triton/triton_p.h b/accel-pppd/triton/triton_p.h
index 443cedea..94017293 100644
--- a/accel-pppd/triton/triton_p.h
+++ b/accel-pppd/triton/triton_p.h
@@ -41,6 +41,7 @@ struct _triton_context_t
int need_free;
int pending;
int priority;
+ int refs;
struct triton_context_t *ud;
void *bf_arg;
@@ -107,5 +108,6 @@ int conf_reload(const char *fname);
void triton_log_error(const char *fmt, ...) __attribute__((format(gnu_printf, 1, 2)));
void triton_log_debug(const char *fmt, ...) __attribute__((format(gnu_printf, 1, 2)));
int load_modules(const char *name);
+void triton_context_release(struct _triton_context_t *ctx);
#endif