diff --git a/include/sntl/sntllv2.h b/include/sntl/sntllv2.h index 4cfa653..d8c2494 100644 --- a/include/sntl/sntllv2.h +++ b/include/sntl/sntllv2.h @@ -90,6 +90,7 @@ typedef struct __connection_t { /* Other stuff */ pthread_t thrd_poll[8]; volatile uint8_t flags; /** < flags of the connection */ + volatile uint8_t usecount; usrtc_node_t csnode; /** < node to store the connection within list */ } conn_t; diff --git a/lib/sntllv2.c b/lib/sntllv2.c index c033ea3..5b4b78d 100644 --- a/lib/sntllv2.c +++ b/lib/sntllv2.c @@ -436,6 +436,63 @@ static int __eval_syssexp(conn_t *co, sexp_t *sx) return rentry->rpcf((void *)co, sx); } +#define _CONN_INUSE(co) (co)->usecount++; +#define _CONN_NOTINUSE(co) (co)->usecount--; +#define _CONN_UCOUNT(co) (co)->usecount + +static void __connection_destroy(conn_t *co) +{ + int i = 0; + sxmsg_t *msg; + chnl_t *chan; + sntllv2_head_t *head; + conn_sys_t *ssys = co->ssys; + + /* first we will unpin all messages and mark it as errors on */ + if(co->unused_messages) { + /*TODO: kill it all */ + } + + /* go thru messages */ + pthread_mutex_lock(&co->idx_msg_lock); + for(i = 0; i < 1024; i++) { + msg = co->messages[i]; + if(!msg) continue; + else head = &msg->mhead; + head->opcode = SNE_LINKERROR; + pthread_mutex_unlock(&msg->wait); + co->messages[i] = NULL; + idx_free(&co->idx_msg, i); + } + pthread_mutex_unlock(&co->idx_msg_lock); + + /* ok now we will free the channels */ + pthread_mutex_lock(&co->idx_ch_lock); + for(i = 0; i < 512; i++) { + chan = co->channels[i]; + if(!chan) continue; + idx_free(&co->idx_ch, i); + free(chan); + } + pthread_mutex_unlock(&co->idx_ch_lock); + + /* update use count */ + _CONN_NOTINUSE(co); + + /* ok, let's free other if we can */ + if(!_CONN_UCOUNT(co)) { + if(ssys->on_destroy) ssys->on_destroy(co); + SSL_shutdown(co->ssl); + close(SSL_get_fd(co->ssl)); + SSL_free(co->ssl); + SSL_CTX_free(co->ctx); + __connection_second_free(co); + __connection_minimal_free(co); + } + + return; +} + static void *__sntll_thread(void *b) { sntllv2_bundle_t *bun = (sntllv2_bundle_t *)b; @@ -468,6 +525,9 @@ static void *__sntll_thread(void *b) if(pthread_equal(self, co->thrd_poll[7])) /* dispatcher */ dispatch = 1; + /* update use count */ + _CONN_INUSE(co); + /* the following logic : (except dispatcher) * 1. check up pending write -> if exists write one and start again., otherwise go next * 2. read from ssl connection (we will sleep if other already acquire the lock) @@ -683,6 +743,7 @@ static void *__sntll_thread(void *b) } __finish: + __connection_destroy(co); __sntll_bundle_destroy(b); /* destroy bundle */ return NULL; }