summaryrefslogtreecommitdiff
path: root/accel-pptpd/triton
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-12-27 15:25:38 +0300
committerKozlov Dmitry <dima@server>2010-12-27 15:25:38 +0300
commit2b34d862111f1fd84cdb9d744ac34c1c933f34da (patch)
tree1e758ddc96689793e1c4c1b55cf3671bb05f2884 /accel-pptpd/triton
parentccaeb500e38d82c37568292d7850b66691793626 (diff)
downloadaccel-ppp-2b34d862111f1fd84cdb9d744ac34c1c933f34da.tar.gz
accel-ppp-2b34d862111f1fd84cdb9d744ac34c1c933f34da.zip
implemented partial config reload via SIGUSR1 signal or cli
Diffstat (limited to 'accel-pptpd/triton')
-rw-r--r--accel-pptpd/triton/conf_file.c91
-rw-r--r--accel-pptpd/triton/triton.c61
-rw-r--r--accel-pptpd/triton/triton.h5
-rw-r--r--accel-pptpd/triton/triton_p.h1
4 files changed, 134 insertions, 24 deletions
diff --git a/accel-pptpd/triton/conf_file.c b/accel-pptpd/triton/conf_file.c
index 6eb2e7a8..ce8549c9 100644
--- a/accel-pptpd/triton/conf_file.c
+++ b/accel-pptpd/triton/conf_file.c
@@ -2,6 +2,7 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
+#include <pthread.h>
#include "triton_p.h"
@@ -14,7 +15,9 @@ struct sect_t
struct conf_sect_t *sect;
};
+static pthread_mutex_t conf_lock = PTHREAD_MUTEX_INITIALIZER;
static LIST_HEAD(sections);
+static char *conf_fname;
static char* skip_space(char *str);
static char* skip_word(char *str);
@@ -24,12 +27,12 @@ static struct conf_sect_t *create_sect(const char *name);
static void sect_add_item(struct conf_sect_t *sect, const char *name, const char *val);
static struct conf_option_t *find_item(struct conf_sect_t *, const char *name);
-int conf_load(const char *fname)
+static char *buf;
+
+int __conf_load(const char *fname, struct conf_sect_t *cur_sect)
{
- char *buf,*str,*str2;
- char *path0,*path;
+ char *str,*str2;
int cur_line = 0;
- static struct conf_sect_t *cur_sect = NULL;
FILE *f = fopen(fname, "r");
if (!f) {
@@ -37,12 +40,6 @@ int conf_load(const char *fname)
return -1;
}
- buf = _malloc(1024);
- path0 = _malloc(4096);
- path = _malloc(4096);
-
- getcwd(path0, 1024);
-
while(!feof(f)) {
if (!fgets(buf, 1024, f))
break;
@@ -56,7 +53,8 @@ int conf_load(const char *fname)
if (strncmp(str, "$include", 8) == 0) {
str = skip_word(str);
str = skip_space(str);
- conf_load(str);
+ if (__conf_load(str, cur_sect));
+ break;
continue;
}
if (*str == '[') {
@@ -104,14 +102,77 @@ int conf_load(const char *fname)
sect_add_item(cur_sect, str, str2);
}
- _free(buf);
- _free(path);
- _free(path0);
fclose(f);
return 0;
}
+int conf_load(const char *fname)
+{
+ int r;
+
+ if (fname) {
+ if (conf_fname)
+ _free(conf_fname);
+ conf_fname = _strdup(fname);
+ } else
+ fname = conf_fname;
+
+ buf = _malloc(1024);
+
+ r = __conf_load(fname, NULL);
+
+ _free(buf);
+
+ return r;
+}
+
+int conf_reload(const char *fname)
+{
+ struct sect_t *sect;
+ struct conf_option_t *opt;
+ int r;
+ LIST_HEAD(sections_bak);
+
+ pthread_mutex_lock(&conf_lock);
+
+ while (!list_empty(&sections)) {
+ sect = list_entry(sections.next, typeof(*sect), entry);
+ list_del(&sect->entry);
+ list_add_tail(&sect->entry, &sections_bak);
+ }
+
+ r = conf_load(fname);
+
+ if (r) {
+ while (!list_empty(&sections_bak)) {
+ sect = list_entry(sections_bak.next, typeof(*sect), entry);
+ list_del(&sect->entry);
+ list_add_tail(&sect->entry, &sections);
+ }
+ pthread_mutex_unlock(&conf_lock);
+ } else {
+ pthread_mutex_unlock(&conf_lock);
+ while (!list_empty(&sections_bak)) {
+ sect = list_entry(sections_bak.next, typeof(*sect), entry);
+ list_del(&sect->entry);
+ while (!list_empty(&sect->sect->items)) {
+ opt = list_entry(sect->sect->items.next, typeof(*opt), entry);
+ list_del(&opt->entry);
+ if (opt->val)
+ _free(opt->val);
+ _free(opt->name);
+ _free(opt);
+ }
+ _free((char *)sect->sect->name);
+ _free(sect->sect);
+ _free(sect);
+ }
+ }
+
+ return r;
+}
+
static char* skip_space(char *str)
{
for (; *str && *str == ' '; str++);
@@ -136,7 +197,7 @@ static struct conf_sect_t *create_sect(const char *name)
struct sect_t *s = _malloc(sizeof(struct sect_t));
s->sect = _malloc(sizeof(struct conf_sect_t));
- s->sect->name = (char*)strdup(name);
+ s->sect->name = (char*)_strdup(name);
INIT_LIST_HEAD(&s->sect->items);
list_add_tail(&s->entry, &sections);
diff --git a/accel-pptpd/triton/triton.c b/accel-pptpd/triton/triton.c
index 3ed14ffd..7d262512 100644
--- a/accel-pptpd/triton/triton.c
+++ b/accel-pptpd/triton/triton.c
@@ -24,6 +24,9 @@ static LIST_HEAD(ctx_list);
static int terminate;
static int need_terminate;
+static int need_config_reload;
+static void (*config_reload_notify)(int);
+
static mempool_t *ctx_pool;
static mempool_t *call_pool;
static mempool_t *ctx_stack_pool;
@@ -41,6 +44,8 @@ static struct triton_timer_t ru_timer = {
};
struct triton_context_t default_ctx;
+static struct triton_context_t __thread *this_ctx;
+
#define log_debug2(fmt, ...)
void triton_thread_wakeup(struct _triton_thread_t *thread)
@@ -49,6 +54,23 @@ void triton_thread_wakeup(struct _triton_thread_t *thread)
pthread_kill(thread->thread, SIGUSR1);
}
+static void __config_reload(void (*notify)(int))
+{
+ struct _triton_thread_t *t;
+ int r;
+
+ log_debug2("config_reload: enter\n");
+ r = conf_reload(NULL);
+ notify(r);
+
+ spin_lock(&threads_lock);
+ need_config_reload = 0;
+ list_for_each_entry(t, &threads, entry)
+ triton_thread_wakeup(t);
+ spin_unlock(&threads_lock);
+ log_debug2("config_reload: exit\n");
+}
+
static void* triton_thread(struct _triton_thread_t *thread)
{
sigset_t set;
@@ -65,7 +87,7 @@ static void* triton_thread(struct _triton_thread_t *thread)
while (1) {
spin_lock(&threads_lock);
- if (!list_empty(&ctx_queue)) {
+ if (!list_empty(&ctx_queue) && !need_config_reload) {
thread->ctx = list_entry(ctx_queue.next, typeof(*thread->ctx), entry2);
log_debug2("thread: %p: dequeued ctx %p\n", thread, thread->ctx);
list_del(&thread->ctx->entry2);
@@ -79,18 +101,24 @@ static void* triton_thread(struct _triton_thread_t *thread)
log_debug2("thread: %p: sleeping\n", thread);
if (!terminate)
list_add(&thread->entry2, &sleep_threads);
- spin_unlock(&threads_lock);
+
+ if (--triton_stat.thread_active == 0 && need_config_reload) {
+ spin_unlock(&threads_lock);
+ __config_reload(config_reload_notify);
+ } else
+ spin_unlock(&threads_lock);
+
if (terminate)
return NULL;
- __sync_sub_and_fetch(&triton_stat.thread_active, 1);
//printf("thread %p: enter sigwait\n", thread);
sigwait(&set, &sig);
//printf("thread %p: exit sigwait\n", thread);
- __sync_add_and_fetch(&triton_stat.thread_active, 1);
spin_lock(&threads_lock);
+ ++triton_stat.thread_active;
if (!thread->ctx) {
+ list_del(&thread->entry2);
spin_unlock(&threads_lock);
continue;
}
@@ -99,6 +127,7 @@ static void* triton_thread(struct _triton_thread_t *thread)
cont:
log_debug2("thread %p: ctx=%p %p\n", thread, thread->ctx, thread->ctx ? thread->ctx->thread : NULL);
+ this_ctx = thread->ctx->ud;
if (thread->ctx->ud->before_switch)
thread->ctx->ud->before_switch(thread->ctx->ud, thread->ctx->bf_arg);
@@ -229,7 +258,7 @@ int triton_queue_ctx(struct _triton_context_t *ctx)
return 0;
spin_lock(&threads_lock);
- if (list_empty(&sleep_threads)) {
+ if (list_empty(&sleep_threads) || need_config_reload) {
if (ctx->priority)
list_add(&ctx->entry2, &ctx_queue);
else
@@ -343,7 +372,6 @@ void __export triton_context_unregister(struct triton_context_t *ud)
}
spin_unlock(&ctx_list_lock);
-
if (terminate) {
list_for_each_entry(t, &threads, entry)
triton_thread_wakeup(t);
@@ -357,9 +385,9 @@ void __export triton_context_set_priority(struct triton_context_t *ud, int prio)
ctx->priority = prio > 0;
}
-void __export triton_context_schedule(struct triton_context_t *ud)
+void __export triton_context_schedule()
{
- struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd;
+ struct _triton_context_t *ctx = (struct _triton_context_t *)this_ctx->tpd;
ucontext_t *uctx = &ctx->thread->uctx;
spin_lock(&ctx->lock);
@@ -380,6 +408,11 @@ void __export triton_context_schedule(struct triton_context_t *ud)
log_debug2("ctx %p: exit schedule\n", ctx);
}
+struct triton_context_t __export *triton_context_self(void)
+{
+ return this_ctx;
+}
+
void triton_context_print(void)
{
struct _triton_context_t *ctx;
@@ -522,6 +555,18 @@ int __export triton_load_modules(const char *mod_sect)
return 0;
}
+void __export triton_conf_reload(void (*notify)(int))
+{
+ spin_lock(&threads_lock);
+ need_config_reload = 1;
+ config_reload_notify = notify;
+ if (triton_stat.thread_active == 0) {
+ spin_unlock(&threads_lock);
+ __config_reload(notify);
+ } else
+ spin_unlock(&threads_lock);
+}
+
void __export triton_run()
{
struct _triton_thread_t *t;
diff --git a/accel-pptpd/triton/triton.h b/accel-pptpd/triton/triton.h
index a4664ffb..2c3871ea 100644
--- a/accel-pptpd/triton/triton.h
+++ b/accel-pptpd/triton/triton.h
@@ -72,10 +72,11 @@ extern struct triton_stat_t triton_stat;
int triton_context_register(struct triton_context_t *, void *arg);
void triton_context_unregister(struct triton_context_t *);
void triton_context_set_priority(struct triton_context_t *, int);
-void triton_context_schedule(struct triton_context_t *);
+void triton_context_schedule(void);
int triton_context_wakeup(struct triton_context_t *);
int triton_context_call(struct triton_context_t *, void (*func)(void *), void *arg);
void triton_cancel_call(struct triton_context_t *, void (*func)(void *));
+struct triton_context_t *triton_context_self(void);
#define MD_MODE_READ 1
#define MD_MODE_WRITE 2
@@ -99,10 +100,12 @@ void triton_event_fire(int ev_id, void *arg);
struct conf_sect_t *conf_get_section(const char *name);
char *conf_get_opt(const char *sect, const char *name);
+void triton_conf_reload(void (*notify)(int));
void triton_collect_cpu_usage(void);
void triton_stop_collect_cpu_usage(void);
+
#define TRITON_OK 0
#define TRITON_ERR_NOCOMP -1
#define TRITON_ERR_NOSUPP -2
diff --git a/accel-pptpd/triton/triton_p.h b/accel-pptpd/triton/triton_p.h
index 2bc265cb..5804007a 100644
--- a/accel-pptpd/triton/triton_p.h
+++ b/accel-pptpd/triton/triton_p.h
@@ -99,6 +99,7 @@ extern struct triton_context_t default_ctx;
int triton_queue_ctx(struct _triton_context_t*);
void triton_thread_wakeup(struct _triton_thread_t*);
int conf_load(const char *fname);
+int conf_reload(const char *fname);
void triton_log_error(const char *fmt,...);
void triton_log_debug(const char *fmt,...);
int load_modules(const char *name);