Skip to content

Commit

Permalink
cgrates: add ref counters for acc ctx
Browse files Browse the repository at this point in the history
  • Loading branch information
razvancrainea committed Jan 25, 2017
1 parent b4badab commit c4544be
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 30 deletions.
72 changes: 48 additions & 24 deletions modules/cgrates/cgrates_acc.c
Expand Up @@ -24,6 +24,15 @@
#include "cgrates_common.h"
#include "cgrates_acc.h"

#define CGR_REF_CHG(_c, _n) \
do { \
lock_get(&_c->ref_lock); \
_c->ref_no+= _n; \
lock_release(&_c->ref_lock); \
} while(0)
#define CGR_REF_INC(_c) CGR_REF_CHG(_c, 1)
#define CGR_REF_DEC(_c) CGR_REF_CHG(_c, -1)

struct dlg_binds cgr_dlgb;
struct tm_binds cgr_tmb;

Expand Down Expand Up @@ -61,6 +70,9 @@ static inline struct cgr_acc_ctx *cgr_get_acc_ctx(void)
LM_DBG("new acc ctx=%p\n", ctx->acc);
ctxstr.len = sizeof(ctx->acc);
ctxstr.s = (char *)&ctx->acc;

ctx->acc->ref_no = 1;
lock_init(&ctx->acc->ref_lock);
if (cgr_dlgb.store_dlg_value(dlg, &cgr_ctx_str, &ctxstr))
LM_ERR("cannot store context in dialog!\n");
} else {
Expand Down Expand Up @@ -120,18 +132,29 @@ static inline void cgr_free_acc_ctx(struct cgr_acc_ctx *ctx)
struct list_head *l;
struct list_head *t;

LM_DBG("release acc ctx=%p\n", ctx);
if (ctx->acc.s)
shm_free(ctx->acc.s);
if (ctx->dst.s)
shm_free(ctx->dst.s);
/* remove all elements */
if (ctx->kv_store) {
list_for_each_safe(l, t, ctx->kv_store)
cgr_free_kv(list_entry(l, struct cgr_kv, list));
shm_free(ctx->kv_store);
}
shm_free(ctx);
lock_get(&ctx->ref_lock);
ctx->ref_no--;

if (ctx->ref_no == 0) {
LM_DBG("release acc ctx=%p\n", ctx);
if (ctx->acc.s)
shm_free(ctx->acc.s);
if (ctx->dst.s)
shm_free(ctx->dst.s);
/* remove all elements */
if (ctx->kv_store) {
list_for_each_safe(l, t, ctx->kv_store)
cgr_free_kv(list_entry(l, struct cgr_kv, list));
shm_free(ctx->kv_store);
}
shm_free(ctx);
} else if (ctx->ref_no < 0) {
LM_BUG("ref=%d ctx=%p gone negative!\n", ctx->ref_no, ctx);
} else {
LM_DBG("ref=%d ctx=%p\n", ctx->ref_no, ctx);
}

lock_release(&ctx->ref_lock);
}

static int cgr_proc_start_acc_reply(struct cgr_conn *c, json_object *jobj,
Expand Down Expand Up @@ -392,7 +415,6 @@ static void cgr_cdr(struct sip_msg *msg, struct cgr_acc_ctx *ctx, str *callid)
}

cgr_handle_cmd(msg, jmsg, cgr_proc_cdr_acc_reply, ctx);
cgr_free_acc_ctx(ctx);
}

int w_cgr_acc(struct sip_msg* msg, char* acc_c, char *dst_c)
Expand Down Expand Up @@ -435,8 +457,14 @@ int w_cgr_acc(struct sip_msg* msg, char* acc_c, char *dst_c)
}

/* TODO: check if it was already engaged! */
if (cgr_tmb.register_tmcb( msg, 0, TMCB_RESPONSE_OUT|TMCB_ON_FAILURE|
TMCB_TRANS_CANCELLED, cgr_tmcb_func, ctx, cgr_tmcb_func_free)<=0) {
if (cgr_tmb.register_tmcb( msg, 0, TMCB_RESPONSE_OUT,
cgr_tmcb_func, ctx, cgr_tmcb_func_free)<=0) {
LM_ERR("cannot register tm callbacks\n");
goto internal_error;
}

if (cgr_tmb.register_tmcb( msg, 0, TMCB_ON_FAILURE|TMCB_TRANS_CANCELLED,
cgr_tmcb_func, ctx, NULL)<=0) {
LM_ERR("cannot register tm callbacks\n");
goto internal_error;
}
Expand All @@ -455,11 +483,7 @@ int w_cgr_acc(struct sip_msg* msg, char* acc_c, char *dst_c)

static void cgr_tmcb_func_free(void *param)
{
struct cgr_acc_ctx *ctx = (struct cgr_acc_ctx *)param;
/* only free in the EARLY state, because if ENGAGED, then dialog takes
* care of it */
if (ctx->state == CGRS_EARLY)
cgr_free_acc_ctx(ctx);
cgr_free_acc_ctx((struct cgr_acc_ctx *)param);
}

static void cgr_tmcb_func( struct cell* t, int type, struct tmcb_params *ps)
Expand Down Expand Up @@ -500,7 +524,7 @@ static void cgr_tmcb_func( struct cell* t, int type, struct tmcb_params *ps)
if (cgr_handle_cmd(ps->req, jmsg, cgr_proc_start_acc_reply, dlg) < 0)
goto error;

ctx->state = CGRS_ENGAGED;
CGR_REF_INC(ctx);
return;
error:
terminate_str.s = "CGRateS Accounting Denied";
Expand All @@ -524,6 +548,7 @@ static void cgr_cdr_cb(struct cell* t, int type, struct tmcb_params *ps)
ctx = *ps->param;

cgr_cdr(ps->req, ctx, &dlg->callid);
cgr_free_acc_ctx(ctx);
}

static void cgr_dlg_callback(struct dlg_cell *dlg, int type,
Expand Down Expand Up @@ -560,11 +585,10 @@ static void cgr_dlg_callback(struct dlg_cell *dlg, int type,
goto free_ctx;
}
return;
/* for local transactions we generate CDRs here, since all the messages
* have been processed */
} else if (t != NULL && cgr_tmb.t_is_local(_params->msg)) {
/* for local transactions we generate CDRs here, since all the messages
* have been processed */
cgr_cdr(_params->msg, ctx, &dlg->callid);
return;
}
free_ctx:
cgr_free_acc_ctx(ctx);
Expand Down
8 changes: 2 additions & 6 deletions modules/cgrates/cgrates_acc.h
Expand Up @@ -36,14 +36,10 @@
*/
int w_cgr_acc(struct sip_msg* msg, char* acc_c, char *dst_c);

enum cgr_acc_state {
CGRS_EARLY = 0,
CGRS_ENGAGED
};

struct cgr_acc_ctx {

enum cgr_acc_state state;
int ref_no;
gen_lock_t ref_lock;

/* all branches info */
str acc;
Expand Down

0 comments on commit c4544be

Please sign in to comment.