Skip to content

Commit

Permalink
context: add destroy function for registered ctx vars
Browse files Browse the repository at this point in the history
  • Loading branch information
razvancrainea committed Oct 26, 2015
1 parent 440ab21 commit fdf38ed
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 52 deletions.
145 changes: 116 additions & 29 deletions context.c
Expand Up @@ -25,20 +25,104 @@
#include "str.h"
#include "mem/mem.h"
#include "context.h"
#include <string.h>

/* Pointer to the current processing context */
context_p current_processing_ctx = NULL;

unsigned int context_sizes[CONTEXT_COUNT];

static unsigned int type_sizes[CONTEXT_COUNT][3];
static unsigned int type_offsets[CONTEXT_COUNT][3];
enum osips_context_val {
CONTEXT_INT_TYPE,
CONTEXT_STR_TYPE,
CONTEXT_PTR_TYPE,

context_p context_alloc(void)
CONTEXT_COUNT_TYPE
};

static unsigned int type_sizes[CONTEXT_COUNT][CONTEXT_COUNT_TYPE];
static unsigned int type_offsets[CONTEXT_COUNT][CONTEXT_COUNT_TYPE];

/* vector of destroy functions */
static context_destroy_f *context_destroy_array;

static void register_context_destroy(context_destroy_f f,
enum osips_context ctx, enum osips_context_val t)
{
static int count = 0; /* contains all counters */
context_destroy_f *tmp;
int pos = 0;
int i;

/*
* group all functions based on their types:
* first the int functions, then the str and pointers the last
*/
switch (t) {
case CONTEXT_PTR_TYPE:
pos += type_sizes[ctx][CONTEXT_PTR_TYPE];
case CONTEXT_STR_TYPE:
pos += type_sizes[ctx][CONTEXT_STR_TYPE];
case CONTEXT_INT_TYPE:
pos += type_sizes[ctx][CONTEXT_INT_TYPE];
break;
default:
LM_ERR("should not get here with ctx %d\n", t);
return;
}
/* TODO: check whether this should be in pkg or shm? */
tmp = pkg_realloc(context_destroy_array, (count + 1) * sizeof(context_destroy_f));
if (!tmp) {
LM_ERR("cannot add any more destroy functions\n");
return;
}
context_destroy_array = tmp;

/* move everything to the right to make room for pos */
for (i = count; i > pos; i--)
context_destroy_array[i] = context_destroy_array[i - 1];
context_destroy_array[pos] = f;
count++;
}

void context_destroy(enum osips_context ctxtype, context_p ctx)
{
int f = 0;
int n;
int i;
str *s;
void *p;

/* int ctx */
for (n = 0; n < type_sizes[ctxtype][CONTEXT_INT_TYPE]; n++, f++)
if (context_destroy_array[f]) {
i = context_get_int(ctxtype, ctx, n);
if (i)/* XXX: should we call for 0 values? */
context_destroy_array[f](&i);
}

/* str ctx */
for (n = 0; n < type_sizes[ctxtype][CONTEXT_STR_TYPE]; n++, f++)
if (context_destroy_array[f]) {
s = context_get_str(ctxtype, ctx, n);
if (s)/* XXX: how do we determine if s is empty? */
context_destroy_array[f](s);
}

/* ptr ctx */
for (n = 0; n < type_sizes[ctxtype][CONTEXT_PTR_TYPE]; n++, f++)
if (context_destroy_array[f]) {
p = context_get_ptr(ctxtype, ctx, n);
if (p)
context_destroy_array[f](p);
}
}

context_p context_alloc(enum osips_context type)
{
context_p ctx;

ctx = pkg_malloc(context_size(CONTEXT_GLOBAL));
ctx = pkg_malloc(context_size(type));
if (!ctx) {
LM_ERR("no more pkg mem\n");
return NULL;
Expand All @@ -47,36 +131,39 @@ context_p context_alloc(void)
return ctx;
}

int context_register_int(enum osips_context type)
int context_register_int(enum osips_context type, context_destroy_f f)
{
context_sizes[type] += sizeof(int);
type_offsets[type][1] += sizeof(int);
type_offsets[type][2] += sizeof(int);
type_offsets[type][CONTEXT_STR_TYPE] += sizeof(int);
type_offsets[type][CONTEXT_PTR_TYPE] += sizeof(int);
register_context_destroy(f, type, CONTEXT_INT_TYPE);

return type_sizes[type][0]++;
return type_sizes[type][CONTEXT_INT_TYPE]++;
}

int context_register_str(enum osips_context type)
int context_register_str(enum osips_context type, context_destroy_f f)
{
context_sizes[type] += sizeof(str);
type_offsets[type][2] += sizeof(str);
type_offsets[type][CONTEXT_PTR_TYPE] += sizeof(str);
register_context_destroy(f, type, CONTEXT_STR_TYPE);

return type_sizes[type][1]++;
return type_sizes[type][CONTEXT_STR_TYPE]++;
}

int context_register_ptr(enum osips_context type)
int context_register_ptr(enum osips_context type, context_destroy_f f)
{
context_sizes[type] += sizeof(void *);
register_context_destroy(f, type, CONTEXT_PTR_TYPE);

return type_sizes[type][2]++;
return type_sizes[type][CONTEXT_PTR_TYPE]++;
}

void context_put_int(enum osips_context type, context_p ctx,
int pos, int data)
{
#ifdef DBG_QM_MALLOC
if (pos < 0 || pos >= type_sizes[type][0]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][0]);
if (pos < 0 || pos >= type_sizes[type][CONTEXT_INT_TYPE]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_INT_TYPE]);
abort();
}
#endif
Expand All @@ -91,39 +178,39 @@ void context_put_str(enum osips_context type, context_p ctx,
int pos, str *data)
{
#ifdef DBG_QM_MALLOC
if (pos < 0 || pos >= type_sizes[type][1]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][1]);
if (pos < 0 || pos >= type_sizes[type][CONTEXT_STR_TYPE]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_STR_TYPE]);
abort();
}
#endif

if (!ctx)
LM_CRIT("NULL context given\n");

((str *)((char *)ctx + type_offsets[type][1]))[pos] = *data;
((str *)((char *)ctx + type_offsets[type][CONTEXT_STR_TYPE]))[pos] = *data;
}

void context_put_ptr(enum osips_context type, context_p ctx,
int pos, void *data)
{
#ifdef DBG_QM_MALLOC
if (pos < 0 || pos >= type_sizes[type][2]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][2]);
if (pos < 0 || pos >= type_sizes[type][CONTEXT_PTR_TYPE]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_PTR_TYPE]);
abort();
}
#endif

if (!ctx)
LM_CRIT("NULL context given\n");

((void **)((char *)ctx + type_offsets[type][2]))[pos] = data;
((void **)((char *)ctx + type_offsets[type][CONTEXT_PTR_TYPE]))[pos] = data;
}

int context_get_int(enum osips_context type, context_p ctx, int pos)
{
#ifdef DBG_QM_MALLOC
if (pos < 0 || pos >= type_sizes[type][0]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][0]);
if (pos < 0 || pos >= type_sizes[type][CONTEXT_INT_TYPE]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_INT_TYPE]);
abort();
}
#endif
Expand All @@ -137,29 +224,29 @@ int context_get_int(enum osips_context type, context_p ctx, int pos)
str *context_get_str(enum osips_context type, context_p ctx, int pos)
{
#ifdef DBG_QM_MALLOC
if (pos < 0 || pos >= type_sizes[type][1]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][1]);
if (pos < 0 || pos >= type_sizes[type][CONTEXT_STR_TYPE]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_STR_TYPE]);
abort();
}
#endif

if (!ctx)
LM_CRIT("NULL context given\n");

return &((str *)((char *)ctx + type_offsets[type][1]))[pos];
return &((str *)((char *)ctx + type_offsets[type][CONTEXT_STR_TYPE]))[pos];
}

void *context_get_ptr(enum osips_context type, context_p ctx, int pos)
{
#ifdef DBG_QM_MALLOC
if (pos < 0 || pos >= type_sizes[type][2]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][2]);
if (pos < 0 || pos >= type_sizes[type][CONTEXT_PTR_TYPE]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_PTR_TYPE]);
abort();
}
#endif

if (!ctx)
LM_CRIT("NULL context given\n");

return ((void **)((char *)ctx + type_offsets[type][2]))[pos];
return ((void **)((char *)ctx + type_offsets[type][CONTEXT_PTR_TYPE]))[pos];
}
15 changes: 11 additions & 4 deletions context.h
Expand Up @@ -58,18 +58,25 @@ extern unsigned int context_sizes[];
*
* Note: this will not change the "current_processing_ctx"
*/
context_p context_alloc(void);
context_p context_alloc(enum osips_context ctx);
#define context_free(context_p) pkg_free(context_p)

/*
* destroys a context by calling each callback registered
*/
void context_destroy(enum osips_context type, context_p ctx);

typedef void (*context_destroy_f)(void *);

/*
* - the register functions should be called before any forks are made
* (mod_init(), function fixups)
*
* - they reserve and return a position in the context buffer of the given type
*/
int context_register_int(enum osips_context type);
int context_register_str(enum osips_context type);
int context_register_ptr(enum osips_context type);
int context_register_int(enum osips_context type, context_destroy_f f);
int context_register_str(enum osips_context type, context_destroy_f f);
int context_register_ptr(enum osips_context type, context_destroy_f f);

void context_put_int(enum osips_context type, context_p ctx,
int pos, int data);
Expand Down
4 changes: 2 additions & 2 deletions modules/compression/compression.c
Expand Up @@ -378,10 +378,10 @@ static int mod_init(void)
mc_level = 6;
}

compress_ctx_pos = context_register_ptr(CONTEXT_GLOBAL);
compress_ctx_pos = context_register_ptr(CONTEXT_GLOBAL, NULL);
LM_DBG("received compress context postion %d\n", compress_ctx_pos);

compact_ctx_pos = context_register_ptr(CONTEXT_GLOBAL);
compact_ctx_pos = context_register_ptr(CONTEXT_GLOBAL, NULL);
LM_DBG("received compact context postion %d\n", compact_ctx_pos);

memset(&tm_api, 0, sizeof(struct tm_binds));
Expand Down
13 changes: 10 additions & 3 deletions modules/dialog/dialog.c
Expand Up @@ -663,6 +663,13 @@ static int pv_get_dlg_count(struct sip_msg *msg, pv_param_t *param,
return 0;
}

static void ctx_dlg_idx_destroy(void *v)
{
unref_dlg((struct dlg_cell*)v, 1);
/* reset the pointer to make sure no-one is trying to free it anymore */
ctx_dialog_set(NULL);
}


static int mod_init(void)
{
Expand Down Expand Up @@ -757,9 +764,9 @@ static int mod_init(void)
}

/* allocate a slot in the processing context */
ctx_dlg_idx = context_register_ptr(CONTEXT_GLOBAL);
ctx_timeout_idx = context_register_int(CONTEXT_GLOBAL);
ctx_lastdstleg_idx = context_register_int(CONTEXT_GLOBAL);
ctx_dlg_idx = context_register_ptr(CONTEXT_GLOBAL, ctx_dlg_idx_destroy);
ctx_timeout_idx = context_register_int(CONTEXT_GLOBAL, NULL);
ctx_lastdstleg_idx = context_register_int(CONTEXT_GLOBAL, NULL);

/* create dialog state changed event */
if (state_changed_event_init() < 0) {
Expand Down
2 changes: 2 additions & 0 deletions modules/dialog/dlg_handlers.c
Expand Up @@ -1489,6 +1489,8 @@ void dlg_ontimeout( struct dlg_tl *tl)

if (current_processing_ctx == NULL)
*new_ctx = NULL;
else
context_destroy(CONTEXT_GLOBAL, *new_ctx);

/* reset the processing context */
current_processing_ctx = old_ctx;
Expand Down
6 changes: 6 additions & 0 deletions modules/dialog/dlg_req_within.c
Expand Up @@ -258,6 +258,8 @@ static void dual_bye_event(struct dlg_cell* dlg, struct sip_msg *req, int extra_
/* reset the processing context */
if (current_processing_ctx == NULL)
*new_ctx = NULL;
else
context_destroy(CONTEXT_GLOBAL, *new_ctx);
current_processing_ctx = old_ctx;
} /* no CB run in case of failure FIXME */
} else {
Expand Down Expand Up @@ -383,6 +385,8 @@ static inline int send_leg_bye(struct dlg_cell *cell, int dst_leg, int src_leg,
/* reset the processing contect */
if (current_processing_ctx == NULL)
*new_ctx = NULL;
else
context_destroy(CONTEXT_GLOBAL, *new_ctx);
current_processing_ctx = old_ctx;

if(result < 0){
Expand Down Expand Up @@ -567,6 +571,8 @@ int send_leg_msg(struct dlg_cell *dlg,str *method,int src_leg,int dst_leg,
/* reset the processing contect */
if (current_processing_ctx == NULL)
*new_ctx = NULL;
else
context_destroy(CONTEXT_GLOBAL, *new_ctx);
current_processing_ctx = old_ctx;

if(result < 0)
Expand Down
2 changes: 1 addition & 1 deletion modules/dialog/dlg_req_within.h
Expand Up @@ -61,7 +61,7 @@ static inline int push_new_processing_context( struct dlg_cell *dlg,

*old_ctx = current_processing_ctx;
if (my_ctx==NULL) {
my_ctx = context_alloc();
my_ctx = context_alloc(CONTEXT_GLOBAL);
if (my_ctx==NULL) {
LM_ERR("failed to alloc new ctx in pkg\n");
return -1;
Expand Down
2 changes: 1 addition & 1 deletion modules/pua_usrloc/pua_usrloc.c
Expand Up @@ -135,7 +135,7 @@ static int mod_init(void)
}

/* index in global context to keep the on/off state */
pul_status_idx = context_register_int(CONTEXT_GLOBAL);
pul_status_idx = context_register_int(CONTEXT_GLOBAL, NULL);

bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
if (!bind_usrloc)
Expand Down
6 changes: 3 additions & 3 deletions modules/rr/rr_mod.c
Expand Up @@ -178,9 +178,9 @@ static int mod_init(void)
{
LM_INFO("rr - initializing\n");

ctx_rrparam_idx = context_register_str(CONTEXT_GLOBAL);
ctx_routing_idx = context_register_int(CONTEXT_GLOBAL);
ctx_rrdone_idx = context_register_int(CONTEXT_GLOBAL);
ctx_rrparam_idx = context_register_str(CONTEXT_GLOBAL, NULL);
ctx_routing_idx = context_register_int(CONTEXT_GLOBAL, NULL);
ctx_rrdone_idx = context_register_int(CONTEXT_GLOBAL, NULL);

#ifdef ENABLE_USER_CHECK
if(ignore_user)
Expand Down
2 changes: 1 addition & 1 deletion modules/rtpengine/rtpengine.c
Expand Up @@ -759,7 +759,7 @@ mod_init(void)
unsigned short avp_flags;
str s;

ctx_rtpeset_idx = context_register_ptr(CONTEXT_GLOBAL);
ctx_rtpeset_idx = context_register_ptr(CONTEXT_GLOBAL, NULL);

/* any rtpengine configured? */
if(rtpe_set_list)
Expand Down

0 comments on commit fdf38ed

Please sign in to comment.