summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel-pptpd/CMakeLists.txt4
-rw-r--r--accel-pptpd/accel-pptpd.conf7
-rw-r--r--accel-pptpd/ctrl/pptp.c47
-rw-r--r--accel-pptpd/log.c17
-rw-r--r--accel-pptpd/log.h1
-rw-r--r--accel-pptpd/logs/log_file.c24
-rw-r--r--accel-pptpd/logs/log_pgsql.c30
-rw-r--r--accel-pptpd/main.c7
-rw-r--r--accel-pptpd/ppp/ppp.c8
-rw-r--r--accel-pptpd/ppp/ppp.h1
-rw-r--r--accel-pptpd/ppp/ppp_ccp.c6
-rw-r--r--accel-pptpd/ppp/ppp_fsm.c2
-rw-r--r--accel-pptpd/ppp/ppp_fsm.h1
-rw-r--r--accel-pptpd/ppp/ppp_ipcp.c7
-rw-r--r--accel-pptpd/ppp/ppp_lcp.c3
-rw-r--r--accel-pptpd/radius/dm_coa.c1
-rw-r--r--accel-pptpd/triton/triton.c43
17 files changed, 157 insertions, 52 deletions
diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt
index 3de0072d..9254e7e9 100644
--- a/accel-pptpd/CMakeLists.txt
+++ b/accel-pptpd/CMakeLists.txt
@@ -12,7 +12,7 @@ ADD_SUBDIRECTORY(radius)
ADD_SUBDIRECTORY(logs)
ADD_SUBDIRECTORY(extra)
-ADD_EXECUTABLE(pptpd
+ADD_EXECUTABLE(accel-pptpd
ppp/ppp.c
ppp/ppp_fsm.c
ppp/ppp_lcp.c
@@ -39,5 +39,5 @@ ADD_EXECUTABLE(pptpd
main.c
memdebug.c
)
-TARGET_LINK_LIBRARIES(pptpd triton rt pthread ssl)
+TARGET_LINK_LIBRARIES(accel-pptpd triton rt pthread ssl)
diff --git a/accel-pptpd/accel-pptpd.conf b/accel-pptpd/accel-pptpd.conf
index d14fe180..bc74c2c9 100644
--- a/accel-pptpd/accel-pptpd.conf
+++ b/accel-pptpd/accel-pptpd.conf
@@ -1,6 +1,6 @@
[modules]
./liblog_file.so
-./liblog_pgsql.so
+#./liblog_pgsql.so
./libpptp.so
./libauth_pap.so
./libauth_chap_md5.so
@@ -36,10 +36,11 @@ dm_coa_secret=testing123
verbose=1
[client-ip-range]
-192.168.10.20-20
+192.168.10.20-30
192.168.10.6/32
192.168.10.1/32
192.168.11.0/24
+192.168.0.0/24
[ip-pool]
gw-ip-address=192.168.100.1
@@ -53,7 +54,7 @@ gw-ip-address=192.168.100.1
[log]
log-file=general.log
log-emerg=/dev/stderr
-log-debug=debug.log
+log-debug=/dev/stdout
copy=1
#color=1
#per-user-dir=per_user
diff --git a/accel-pptpd/ctrl/pptp.c b/accel-pptpd/ctrl/pptp.c
index f4cd9d3a..4c27610d 100644
--- a/accel-pptpd/ctrl/pptp.c
+++ b/accel-pptpd/ctrl/pptp.c
@@ -117,12 +117,11 @@ static int post_msg(struct pptp_conn_t *conn, void *buf, int size)
return 0;
}
-static int send_pptp_stop_ctrl_conn_rqst(struct pptp_conn_t *conn, int reason, int err_code)
+static int send_pptp_stop_ctrl_conn_rqst(struct pptp_conn_t *conn, int reason)
{
struct pptp_stop_ctrl_conn msg = {
.header = PPTP_HEADER_CTRL(PPTP_STOP_CTRL_CONN_RQST),
.reason_result = hton8(reason),
- .error_code = hton8(err_code),
};
return post_msg(conn, &msg, sizeof(msg));
@@ -143,12 +142,13 @@ static int pptp_stop_ctrl_conn_rqst(struct pptp_conn_t *conn)
struct pptp_stop_ctrl_conn *msg = (struct pptp_stop_ctrl_conn *)conn->in_buf;
log_ppp_info("PPTP_STOP_CTRL_CONN_RQST reason=%i error_code=%i\n",msg->reason_result, msg->error_code);
- if (conn->state == STATE_PPP) {
- conn->state = STATE_FIN;
- ppp_terminate(&conn->ppp, 0);
- }
-
send_pptp_stop_ctrl_conn_rply(conn, PPTP_CONN_STOP_OK, 0);
+
+ return -1;
+}
+
+static int pptp_stop_ctrl_conn_rply(struct pptp_conn_t *conn)
+{
return -1;
}
@@ -173,6 +173,7 @@ static int send_pptp_start_ctrl_conn_rply(struct pptp_conn_t *conn, int res_code
return post_msg(conn, &msg, sizeof(msg));
}
+
static int pptp_start_ctrl_conn_rqst(struct pptp_conn_t *conn)
{
struct pptp_start_ctrl_conn *msg = (struct pptp_start_ctrl_conn *)conn->in_buf;
@@ -190,12 +191,12 @@ static int pptp_start_ctrl_conn_rqst(struct pptp_conn_t *conn)
return -1;
return 0;
}
- if (!(ntohl(msg->framing_cap) & PPTP_FRAME_SYNC)) {
+ /*if (!(ntohl(msg->framing_cap) & PPTP_FRAME_SYNC)) {
log_ppp_warn("connection does not supports sync mode\n");
if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_GE, 0))
return -1;
return 0;
- }
+ }*/
if (send_pptp_start_ctrl_conn_rply(conn, PPTP_CONN_RES_SUCCESS, 0))
return -1;
@@ -350,6 +351,8 @@ static int process_packet(struct pptp_conn_t *conn)
return pptp_start_ctrl_conn_rqst(conn);
case PPTP_STOP_CTRL_CONN_RQST:
return pptp_stop_ctrl_conn_rqst(conn);
+ case PPTP_STOP_CTRL_CONN_RPLY:
+ return pptp_stop_ctrl_conn_rply(conn);
case PPTP_OUT_CALL_RQST:
return pptp_out_call_rqst(conn);
case PPTP_ECHO_RQST:
@@ -438,10 +441,18 @@ static void pptp_close(struct triton_context_t *ctx)
{
struct pptp_conn_t *conn = container_of(ctx, typeof(*conn), ctx);
if (conn->state == STATE_PPP) {
- conn->state = STATE_FIN;
+ conn->state = STATE_CLOSE;
ppp_terminate(&conn->ppp, 0);
- } else
- disconnect(conn);
+ } else {
+ if (send_pptp_stop_ctrl_conn_rqst(conn, 0))
+ triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn);
+ else {
+ if (conn->timeout_timer.tpd)
+ triton_timer_mod(&conn->timeout_timer, 0);
+ else
+ triton_timer_add(ctx, &conn->timeout_timer, 0);
+ }
+ }
}
static void ppp_started(struct ppp_t *ppp)
{
@@ -451,11 +462,18 @@ static void ppp_finished(struct ppp_t *ppp)
{
struct pptp_conn_t *conn = container_of(ppp, typeof(*conn), ppp);
- //send_pptp_stop_ctrl_conn_rqst(conn, 0, 0);
if (conn->state != STATE_CLOSE) {
log_ppp_debug("ppp_finished\n");
conn->state = STATE_CLOSE;
- triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn);
+
+ if (send_pptp_stop_ctrl_conn_rqst(conn, 0))
+ triton_context_call(&conn->ctx, (void (*)(void*))disconnect, conn);
+ else {
+ if (conn->timeout_timer.tpd)
+ triton_timer_mod(&conn->timeout_timer, 0);
+ else
+ triton_timer_add(&conn->ctx, &conn->timeout_timer, 0);
+ }
}
}
@@ -540,6 +558,7 @@ static void pptp_serv_close(struct triton_context_t *ctx)
struct pptp_serv_t *s=container_of(ctx,typeof(*s),ctx);
triton_md_unregister_handler(&s->hnd);
close(s->hnd.fd);
+ triton_context_unregister(ctx);
}
static struct pptp_serv_t serv=
diff --git a/accel-pptpd/log.c b/accel-pptpd/log.c
index fee1b548..e942686b 100644
--- a/accel-pptpd/log.c
+++ b/accel-pptpd/log.c
@@ -5,6 +5,7 @@
#include <errno.h>
#include <string.h>
#include <stdint.h>
+#include <signal.h>
#include <sys/time.h>
#include "triton/mempool.h"
@@ -402,14 +403,27 @@ void __export log_switch(struct triton_context_t *ctx, void *arg)
cur_ppp = (struct ppp_t *)arg;
}
+
void __export log_register_target(struct log_target_t *t)
{
list_add_tail(&t->entry, &targets);
}
+static void sighup(int n)
+{
+ struct log_target_t *t;
+
+ list_for_each_entry(t, &targets, entry)
+ if (t->reopen)
+ t->reopen();
+}
+
static void __init log_init(void)
{
char *opt;
+ struct sigaction sa = {
+ .sa_handler = sighup,
+ };
opt = conf_get_opt("log", "log-emerg");
if (opt) {
@@ -428,4 +442,7 @@ static void __init log_init(void)
msg_pool = mempool_create(sizeof(struct log_msg_t));
_msg_pool = mempool_create(sizeof(struct _log_msg_t));
chunk_pool = mempool_create(sizeof(struct log_chunk_t) + LOG_CHUNK_SIZE + 1);
+
+ sigaction(SIGHUP, &sa, NULL);
}
+
diff --git a/accel-pptpd/log.h b/accel-pptpd/log.h
index 97894597..140dad1d 100644
--- a/accel-pptpd/log.h
+++ b/accel-pptpd/log.h
@@ -40,6 +40,7 @@ struct log_target_t
struct list_head entry;
void (*log)(struct log_msg_t *, struct ppp_t *ppp);
+ void (*reopen)(void);
};
void log_free_msg(struct log_msg_t *msg);
diff --git a/accel-pptpd/logs/log_file.c b/accel-pptpd/logs/log_file.c
index 79af4c68..26ec3f90 100644
--- a/accel-pptpd/logs/log_file.c
+++ b/accel-pptpd/logs/log_file.c
@@ -34,8 +34,8 @@ struct log_file_t
struct log_file_pd_t *lpd;
int fd;
+ int new_fd;
off_t offset;
- int cnt;
uint64_t magic;
};
@@ -76,14 +76,13 @@ static uint64_t temp_seq;
static void send_next_chunk();
-#define MAGIC 0x9988776655443322llu
static void log_file_init(struct log_file_t *lf)
{
spinlock_init(&lf->lock);
INIT_LIST_HEAD(&lf->msgs);
lf->fd = -1;
- lf->magic = MAGIC;
+ lf->new_fd = -1;
}
static int log_file_open(struct log_file_t *lf, const char *fname)
@@ -201,11 +200,16 @@ static void send_next_chunk(void)
spin_unlock(&lf_queue_lock);
+ if (lf->new_fd != -1) {
+ close(lf->fd);
+ lf->fd = lf->new_fd;
+ lf->new_fd = -1;
+ }
+
aiocb.aio_fildes = lf->fd;
aiocb.aio_offset = lf->offset;
aiocb.aio_sigevent.sigev_value.sival_ptr = lf;
aiocb.aio_nbytes = dequeue_log(lf);
- __sync_add_and_fetch(&lf->cnt, 1);
if (aio_write(&aiocb))
log_emerg("log_file: aio_write: %s\n", strerror(errno));
@@ -323,6 +327,17 @@ static void per_session_log(struct log_msg_t *msg, struct ppp_t *ppp)
queue_log(&lpd->lf, msg);
}
+static void general_reopen(void)
+{
+ char *fname = conf_get_opt("log", "log-file");
+ int fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ log_emerg("log_file: open '%s': %s\n", fname, strerror(errno));
+ return;
+ }
+ log_file->new_fd = fd;
+}
+
static void free_lpd(struct log_file_pd_t *lpd)
{
struct log_msg_t *msg;
@@ -515,6 +530,7 @@ out_err:
static struct log_target_t general_target =
{
.log = general_log,
+ .reopen = general_reopen,
};
static struct log_target_t per_user_target =
diff --git a/accel-pptpd/logs/log_pgsql.c b/accel-pptpd/logs/log_pgsql.c
index 351fc064..0eed2431 100644
--- a/accel-pptpd/logs/log_pgsql.c
+++ b/accel-pptpd/logs/log_pgsql.c
@@ -19,8 +19,11 @@ static char *conf_query;
static void start_connect(void);
static void start_connect_timer(struct triton_timer_t *);
+static void pgsql_close(struct triton_context_t *ctx);
-static struct triton_context_t pgsql_ctx;
+static struct triton_context_t pgsql_ctx = {
+ .close = pgsql_close,
+};
static struct triton_md_handler_t pgsql_hnd;
static struct triton_timer_t connect_timer = {
.period = 5000,
@@ -34,6 +37,7 @@ static int queue_size;
static int sleeping = 0;
static spinlock_t queue_lock = SPINLOCK_INITIALIZER;
static char *log_buf;
+static int need_close;
static void unpack_msg(struct log_msg_t *msg)
{
@@ -80,6 +84,12 @@ static void write_next_msg(void)
if (list_empty(&msg_queue)) {
sleeping = 1;
spin_unlock(&queue_lock);
+ if (need_close) {
+ triton_md_unregister_handler(&pgsql_hnd);
+ PQfinish(conn);
+ conn = NULL;
+ triton_context_unregister(&pgsql_ctx);
+ }
return;
}
@@ -162,6 +172,11 @@ static void queue_log(struct log_msg_t *msg)
{
int r = 0, f = 0;
spin_lock(&queue_lock);
+ if (!conn) {
+ log_free_msg(msg);
+ spin_unlock(&queue_lock);
+ return;
+ }
if (queue_size < conf_queue_max) {
list_add_tail(&msg->entry, &msg_queue);
++queue_size;
@@ -247,6 +262,19 @@ static void start_connect_timer(struct triton_timer_t *t)
start_connect();
}
+static void pgsql_close(struct triton_context_t *ctx)
+{
+ spin_lock(&queue_lock);
+ if (sleeping) {
+ triton_md_unregister_handler(&pgsql_hnd);
+ PQfinish(conn);
+ conn = NULL;
+ triton_context_unregister(&pgsql_ctx);
+ } else
+ need_close = 1;
+ spin_unlock(&queue_lock);
+}
+
static struct log_target_t target = {
.log = general_log,
};
diff --git a/accel-pptpd/main.c b/accel-pptpd/main.c
index afd6b588..b543f0d8 100644
--- a/accel-pptpd/main.c
+++ b/accel-pptpd/main.c
@@ -109,7 +109,7 @@ int main(int argc, char **argv)
}
if (pid_file) {
- FILE *f = fopen("pid_file", "w");
+ FILE *f = fopen(pid_file, "w");
if (f) {
fprintf(f, "%i", getpid());
fclose(f);
@@ -128,10 +128,11 @@ int main(int argc, char **argv)
sigdelset(&set, SIGFPE);
sigdelset(&set, SIGILL);
sigdelset(&set, SIGBUS);
- sigdelset(&set, 35);
- sigdelset(&set, 36);
+ sigdelset(&set, SIGHUP);
sigdelset(&set, SIGIO);
sigdelset(&set, SIGINT);
+ sigdelset(&set, 35);
+ sigdelset(&set, 36);
pthread_sigmask(SIG_SETMASK, &set, NULL);
sigemptyset(&set);
diff --git a/accel-pptpd/ppp/ppp.c b/accel-pptpd/ppp/ppp.c
index dfe5bbe0..f8da0052 100644
--- a/accel-pptpd/ppp/ppp.c
+++ b/accel-pptpd/ppp/ppp.c
@@ -373,6 +373,14 @@ void __export ppp_terminate(struct ppp_t *ppp, int hard)
struct ppp_layer_data_t *d;
int s = 0;
+ if (ppp->terminating) {
+ if (hard)
+ destablish_ppp(ppp);
+ return;
+ }
+
+ ppp->terminating = 1;
+
log_ppp_debug("ppp_terminate\n");
triton_event_fire(EV_PPP_FINISHING, ppp);
diff --git a/accel-pptpd/ppp/ppp.h b/accel-pptpd/ppp/ppp.h
index 5a8ac572..5769f8cb 100644
--- a/accel-pptpd/ppp/ppp.h
+++ b/accel-pptpd/ppp/ppp.h
@@ -86,6 +86,7 @@ struct ppp_t
struct ppp_ctrl_t *ctrl;
int log:1;
+ int terminating:1;
void *chan_buf;
int chan_buf_size;
diff --git a/accel-pptpd/ppp/ppp_ccp.c b/accel-pptpd/ppp/ppp_ccp.c
index 301c2385..e2ee48ac 100644
--- a/accel-pptpd/ppp/ppp_ccp.c
+++ b/accel-pptpd/ppp/ppp_ccp.c
@@ -78,6 +78,7 @@ static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp)
ppp_register_unit_handler(ppp,&ccp->hnd);
+ ccp->fsm.proto = PPP_CCP;
ppp_fsm_init(&ccp->fsm);
ccp->fsm.layer_up=ccp_layer_up;
@@ -544,14 +545,13 @@ static void ccp_recv(struct ppp_handler_t*h)
ppp_fsm_recv_conf_rej(&ccp->fsm);
break;
case TERMREQ:
- term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len));
+ term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4);
log_ppp_debug("recv [CCP TermReq id=%x \"%s\"]\n",hdr->id,term_msg);
_free(term_msg);
ppp_fsm_recv_term_req(&ccp->fsm);
- ppp_terminate(ccp->ppp, 0);
break;
case TERMACK:
- term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len));
+ term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4);
log_ppp_debug("recv [CCP TermAck id=%x \"%s\"]\n",hdr->id,term_msg);
_free(term_msg);
ppp_fsm_recv_term_ack(&ccp->fsm);
diff --git a/accel-pptpd/ppp/ppp_fsm.c b/accel-pptpd/ppp/ppp_fsm.c
index 8f8e8558..62dd8789 100644
--- a/accel-pptpd/ppp/ppp_fsm.c
+++ b/accel-pptpd/ppp/ppp_fsm.c
@@ -477,7 +477,7 @@ void send_term_req(struct ppp_fsm_t *layer)
void send_term_ack(struct ppp_fsm_t *layer)
{
struct lcp_hdr_t hdr = {
- .proto = htons(PPP_LCP),
+ .proto = htons(layer->proto),
.code = TERMACK,
.id = layer->recv_id,
.len = htons(4),
diff --git a/accel-pptpd/ppp/ppp_fsm.h b/accel-pptpd/ppp/ppp_fsm.h
index 908936db..d8624eb7 100644
--- a/accel-pptpd/ppp/ppp_fsm.h
+++ b/accel-pptpd/ppp/ppp_fsm.h
@@ -21,6 +21,7 @@ struct ppp_fsm_t
{
struct ppp_t *ppp;
FSM_STATE fsm_state;
+ uint16_t proto;
struct triton_timer_t restart_timer;
int restart_counter;
diff --git a/accel-pptpd/ppp/ppp_ipcp.c b/accel-pptpd/ppp/ppp_ipcp.c
index f3c20a64..420b9b8d 100644
--- a/accel-pptpd/ppp/ppp_ipcp.c
+++ b/accel-pptpd/ppp/ppp_ipcp.c
@@ -77,7 +77,8 @@ static struct ppp_layer_data_t *ipcp_layer_init(struct ppp_t *ppp)
ipcp->hnd.recv=ipcp_recv;
ppp_register_unit_handler(ppp,&ipcp->hnd);
-
+
+ ipcp->fsm.proto = PPP_IPCP;
ppp_fsm_init(&ipcp->fsm);
ipcp->fsm.layer_up=ipcp_layer_up;
@@ -541,14 +542,14 @@ static void ipcp_recv(struct ppp_handler_t*h)
ppp_fsm_recv_conf_rej(&ipcp->fsm);
break;
case TERMREQ:
- term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len));
+ term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4);
log_ppp_debug("recv [IPCP TermReq id=%x \"%s\"]\n",hdr->id,term_msg);
_free(term_msg);
ppp_fsm_recv_term_req(&ipcp->fsm);
ppp_terminate(ipcp->ppp, 0);
break;
case TERMACK:
- term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len));
+ term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4);
log_ppp_debug("recv [IPCP TermAck id=%x \"%s\"]\n",hdr->id,term_msg);
_free(term_msg);
ppp_fsm_recv_term_ack(&ipcp->fsm);
diff --git a/accel-pptpd/ppp/ppp_lcp.c b/accel-pptpd/ppp/ppp_lcp.c
index 7081cbb3..563936e9 100644
--- a/accel-pptpd/ppp/ppp_lcp.c
+++ b/accel-pptpd/ppp/ppp_lcp.c
@@ -85,7 +85,8 @@ static struct ppp_layer_data_t *lcp_layer_init(struct ppp_t *ppp)
lcp->hnd.recv=lcp_recv;
ppp_register_chan_handler(ppp,&lcp->hnd);
-
+
+ lcp->fsm.proto = PPP_LCP;
ppp_fsm_init(&lcp->fsm);
lcp->fsm.layer_up=lcp_layer_up;
diff --git a/accel-pptpd/radius/dm_coa.c b/accel-pptpd/radius/dm_coa.c
index 32466bbb..d94596fc 100644
--- a/accel-pptpd/radius/dm_coa.c
+++ b/accel-pptpd/radius/dm_coa.c
@@ -235,6 +235,7 @@ static void dm_coa_close(struct triton_context_t *ctx)
struct dm_coa_serv_t *serv = container_of(ctx, typeof(*serv), ctx);
triton_md_unregister_handler(&serv->hnd);
close(serv->hnd.fd);
+ triton_context_unregister(ctx);
}
static struct dm_coa_serv_t serv = {
diff --git a/accel-pptpd/triton/triton.c b/accel-pptpd/triton/triton.c
index d7939041..c4205322 100644
--- a/accel-pptpd/triton/triton.c
+++ b/accel-pptpd/triton/triton.c
@@ -20,8 +20,8 @@ static LIST_HEAD(ctx_queue);
static spinlock_t ctx_list_lock = SPINLOCK_INITIALIZER;
static LIST_HEAD(ctx_list);
-struct triton_context_t *default_ctx;
static int terminate;
+static int need_terminate;
static mempool_t *ctx_pool;
static mempool_t *call_pool;
@@ -268,7 +268,7 @@ int __export triton_context_register(struct triton_context_t *ud, void *bf_arg)
return 0;
}
-int __export triton_context_print()
+void __export triton_context_print()
{
struct _triton_context_t *ctx;
@@ -281,6 +281,7 @@ void __export triton_context_unregister(struct triton_context_t *ud)
{
struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd;
struct _triton_ctx_call_t *call;
+ struct _triton_thread_t *t;
while (!list_empty(&ctx->pending_calls)) {
call = list_entry(ctx->pending_calls.next, typeof(*call), entry);
@@ -290,6 +291,12 @@ void __export triton_context_unregister(struct triton_context_t *ud)
if (!list_empty(&ctx->handlers)) {
triton_log_error("BUG:ctx:triton_unregister_ctx: handlers is not empty");
+ {
+ struct _triton_md_handler_t *h;
+ list_for_each_entry(h, &ctx->handlers, entry)
+ if (h->ud)
+ printf("%p\n", h->ud);
+ }
abort();
}
if (!list_empty(&ctx->pending_handlers)) {
@@ -308,9 +315,16 @@ void __export triton_context_unregister(struct triton_context_t *ud)
ctx->need_free = 1;
spin_lock(&ctx_list_lock);
list_del(&ctx->entry);
+ if (need_terminate && list_empty(&ctx_list))
+ terminate = 1;
spin_unlock(&ctx_list_lock);
__sync_fetch_and_sub(&triton_stat.context_count, 1);
+
+ if (terminate) {
+ list_for_each_entry(t, &threads, entry)
+ triton_thread_wakeup(t);
+ }
}
void __export triton_context_schedule(struct triton_context_t *ud)
{
@@ -391,9 +405,6 @@ int __export triton_init(const char *conf_file)
call_pool = mempool_create(sizeof(struct _triton_ctx_call_t));
ctx_stack_pool = mempool_create(CTX_STACK_SIZE);
- default_ctx = _malloc(sizeof(*default_ctx));
- triton_context_register(default_ctx, NULL);
-
if (conf_load(conf_file))
return -1;
@@ -446,27 +457,25 @@ void __export triton_terminate()
{
struct _triton_context_t *ctx;
struct _triton_thread_t *t;
-
- md_terminate();
- timer_terminate();
-
+ int r;
+
+ need_terminate = 1;
+
spin_lock(&ctx_list_lock);
list_for_each_entry(ctx, &ctx_list, entry) {
spin_lock(&ctx->lock);
ctx->need_close = 1;
- triton_queue_ctx(ctx);
+ r = triton_queue_ctx(ctx);
+ if (r)
+ triton_thread_wakeup(ctx->thread);
spin_unlock(&ctx->lock);
}
spin_unlock(&ctx_list_lock);
- spin_lock(&threads_lock);
- terminate = 1;
- spin_unlock(&threads_lock);
-
- list_for_each_entry(t, &threads, entry)
- triton_thread_wakeup(t);
-
list_for_each_entry(t, &threads, entry)
pthread_join(t->thread, NULL);
+
+ md_terminate();
+ timer_terminate();
}