Skip to content

Commit

Permalink
core context code: add support for a global processing context
Browse files Browse the repository at this point in the history
The newly introduced CONTEXT_GLOBAL represents the current flow of
script execution. It is a more uniform way of handling the majority
of async script usage scenarios.

The initial direction (by simply using CONTEXT_MSG) runs into too many
problems:

    * portions of code where the "current sip_msg" is unavailable
    * concurrency issues (insufficient referencing) due to sip_msg cloning
      logic in tm, which also clones the context, but fails to properly
      count possible additional dialog references

CONTEXT_MSG logic will be removed in a future commit.
  • Loading branch information
liviuchircu committed Dec 10, 2014
1 parent 7eaf122 commit 78c8035
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 125 deletions.
148 changes: 41 additions & 107 deletions context.h
Expand Up @@ -23,133 +23,67 @@
*/

/*
* This header defines the basic operations with an OpenSIPS context.
* It should only be included in order to define operations on a new context.
* This header exposes the basic operations with an OpenSIPS context.
*
* A "context" is:
* - a data storage buffer
* - visible across different processes (stored in shared memory)
* - typically allocated next to the intended structure
* e.g. | struct sip_msg | CONTEXT_BUFFER |
*
* All data registrations must be done in the pre-forking phase (e.g. mod_init)
* e.g. | struct cell | CONTEXT_BUFFER |
*
* !! All data registrations must be done in the pre-forking phases !!
* (see the register functions below)
*/

#ifndef __CONTEXT_H
#define __CONTEXT_H

#include <stdlib.h>

typedef void * context_p;
enum osips_context {
CONTEXT_GLOBAL,
CONTEXT_MSG,
CONTEXT_TRAN,

CONTEXT_COUNT,
};

unsigned int context_sizes[CONTEXT_COUNT];
unsigned int type_sizes[CONTEXT_COUNT][3];
unsigned int type_offsets[CONTEXT_COUNT][3];

#define context_of(entity) ((void *)((entity) + 1))
#define context_size(ctx) (context_sizes[ctx])

static inline int __context_register_int(enum osips_context ctx)
{
context_sizes[ctx] += sizeof(int);
type_offsets[ctx][1] += sizeof(int);
type_offsets[ctx][2] += sizeof(int);

return type_sizes[ctx][0]++;
}

static inline int __context_register_str(enum osips_context ctx)
{
context_sizes[ctx] += sizeof(str);
type_offsets[ctx][2] += sizeof(str);

return type_sizes[ctx][1]++;
}

static inline int __context_register_ptr(enum osips_context ctx)
{
context_sizes[ctx] += sizeof(void *);

return type_sizes[ctx][2]++;
}

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

((int *)block)[pos] = data;
}

static inline void __context_put_str(enum osips_context ctx, void *block,
int pos, str *data)
{
#ifdef DBG_QM_MALLOC
if (pos < 0 || pos >= type_sizes[ctx][1]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[ctx][1]);
abort();
}
#endif
#define context_of(entity_p) ((context_p)((entity_p) + 1))
#define context_size(enum_ctx) (context_sizes[enum_ctx])

((str *)((char *)block + type_offsets[ctx][1]))[pos] = *data;
}
extern context_p current_ctx;
extern unsigned int context_sizes[];

static inline void __context_put_ptr(enum osips_context ctx, void *block,
int pos, void *data)
{
#ifdef DBG_QM_MALLOC
if (pos < 0 || pos >= type_sizes[ctx][2]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[ctx][2]);
abort();
}
#endif
/* called once, after all modules are initialized */
int context_init(void);

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

static inline int __context_get_int(enum osips_context ctx, void *block, int pos)
{
#ifdef DBG_QM_MALLOC
if (pos < 0 || pos >= type_sizes[ctx][0]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[ctx][0]);
abort();
}
#endif

return ((int *)block)[pos];
}

static inline str *__context_get_str(enum osips_context ctx, void *block, int pos)
{
#ifdef DBG_QM_MALLOC
if (pos < 0 || pos >= type_sizes[ctx][1]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[ctx][1]);
abort();
}
#endif

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

static inline void *__context_get_ptr(enum osips_context ctx, void *block, int pos)
{
#ifdef DBG_QM_MALLOC
if (pos < 0 || pos >= type_sizes[ctx][2]) {
LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[ctx][2]);
abort();
}
#endif
/*
* allocate a new GLOBAL context in pkg mem
*
* Note: this will not change the "current_ctx"
*/
context_p context_alloc(void);
#define context_free(context_p) pkg_free(context_p)

return ((void **)((char *)block + type_offsets[ctx][2]))[pos];
}
/*
* - 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
*/
inline int context_register_int(enum osips_context type);
inline int context_register_str(enum osips_context type);
inline int context_register_ptr(enum osips_context type);

inline void context_put_int(enum osips_context type, context_p ctx,
int pos, int data);
inline void context_put_str(enum osips_context type, context_p ctx,
int pos, str *data);
inline void context_put_ptr(enum osips_context type, context_p ctx,
int pos, void *data);

inline int context_get_int(enum osips_context type, context_p ctx, int pos);
inline str *context_get_str(enum osips_context type, context_p ctx, int pos);
inline void *context_get_ptr(enum osips_context type, context_p ctx, int pos);

#endif /* __CONTEXT_H */
7 changes: 7 additions & 0 deletions main.c
Expand Up @@ -127,6 +127,7 @@
#include "ut.h"
#include "serialize.h"
#include "statistics.h"
#include "context.h"
#include "core_stats.h"
#include "pvar.h"
#include "poll_types.h"
Expand Down Expand Up @@ -1560,6 +1561,12 @@ int main(int argc, char** argv)
goto error;
}

/* init global data context */
if (context_init() != 0) {
LM_ERR("error while initializing global context\n");
goto error;
}

/* register route timers */
if(register_route_timers() < 0) {
LM_ERR("Failed to register timer\n");
Expand Down
18 changes: 9 additions & 9 deletions modules/tm/t_ctx.c
Expand Up @@ -26,45 +26,45 @@

int t_ctx_register_int(void)
{
return __context_register_int(CONTEXT_TRAN);
return context_register_int(CONTEXT_TRAN);
}

int t_ctx_register_str(void)
{
return __context_register_str(CONTEXT_TRAN);
return context_register_str(CONTEXT_TRAN);
}

int t_ctx_register_ptr(void)
{
return __context_register_ptr(CONTEXT_TRAN);
return context_register_ptr(CONTEXT_TRAN);
}

void t_ctx_put_int(struct cell *t, int pos, int data)
{
__context_put_int(CONTEXT_TRAN, context_of(t), pos, data);
context_put_int(CONTEXT_TRAN, context_of(t), pos, data);
}

void t_ctx_put_str(struct cell *t, int pos, str *data)
{
__context_put_str(CONTEXT_TRAN, context_of(t), pos, data);
context_put_str(CONTEXT_TRAN, context_of(t), pos, data);
}

void t_ctx_put_ptr(struct cell *t, int pos, void *data)
{
__context_put_ptr(CONTEXT_TRAN, context_of(t), pos, data);
context_put_ptr(CONTEXT_TRAN, context_of(t), pos, data);
}

int t_ctx_get_int(struct cell *t, int pos)
{
return __context_get_int(CONTEXT_TRAN, context_of(t), pos);
return context_get_int(CONTEXT_TRAN, context_of(t), pos);
}

str *t_ctx_get_str(struct cell *t, int pos)
{
return __context_get_str(CONTEXT_TRAN, context_of(t), pos);
return context_get_str(CONTEXT_TRAN, context_of(t), pos);
}

void *t_ctx_get_ptr(struct cell *t, int pos)
{
return __context_get_ptr(CONTEXT_TRAN, context_of(t), pos);
return context_get_ptr(CONTEXT_TRAN, context_of(t), pos);
}
18 changes: 9 additions & 9 deletions msg_translator.c
Expand Up @@ -2133,45 +2133,45 @@ char *construct_uri(str *protocol,str *username,str *domain,str *port,

int msg_ctx_register_int(void)
{
return __context_register_int(CONTEXT_MSG);
return context_register_int(CONTEXT_MSG);
}

int msg_ctx_register_str(void)
{
return __context_register_str(CONTEXT_MSG);
return context_register_str(CONTEXT_MSG);
}

int msg_ctx_register_ptr(void)
{
return __context_register_ptr(CONTEXT_MSG);
return context_register_ptr(CONTEXT_MSG);
}

void msg_ctx_put_int(struct sip_msg *sip_msg, int pos, int data)
{
__context_put_int(CONTEXT_MSG, context_of(sip_msg), pos, data);
context_put_int(CONTEXT_MSG, context_of(sip_msg), pos, data);
}

void msg_ctx_put_str(struct sip_msg *sip_msg, int pos, str *data)
{
__context_put_str(CONTEXT_MSG, context_of(sip_msg), pos, data);
context_put_str(CONTEXT_MSG, context_of(sip_msg), pos, data);
}

void msg_ctx_put_ptr(struct sip_msg *sip_msg, int pos, void *data)
{
__context_put_ptr(CONTEXT_MSG, context_of(sip_msg), pos, data);
context_put_ptr(CONTEXT_MSG, context_of(sip_msg), pos, data);
}

int msg_ctx_get_int(struct sip_msg *sip_msg, int pos)
{
return __context_get_int(CONTEXT_MSG, context_of(sip_msg), pos);
return context_get_int(CONTEXT_MSG, context_of(sip_msg), pos);
}

str *msg_ctx_get_str(struct sip_msg *sip_msg, int pos)
{
return __context_get_str(CONTEXT_MSG, context_of(sip_msg), pos);
return context_get_str(CONTEXT_MSG, context_of(sip_msg), pos);
}

void *msg_ctx_get_ptr(struct sip_msg *sip_msg, int pos)
{
return __context_get_ptr(CONTEXT_MSG, context_of(sip_msg), pos);
return context_get_ptr(CONTEXT_MSG, context_of(sip_msg), pos);
}

0 comments on commit 78c8035

Please sign in to comment.