Level of the select call is moved to a global variable form the structure
authorMiklos Tirpak <miklos@iptel.org>
Wed, 3 Oct 2007 14:56:32 +0000 (14:56 +0000)
committerMiklos Tirpak <miklos@iptel.org>
Wed, 3 Oct 2007 14:56:32 +0000 (14:56 +0000)
in order to make the select calls shared memory-safe.
Fixes SER-318

select.c
select.h
select_core.c

index 4816707..a87fbb2 100644 (file)
--- a/select.c
+++ b/select.c
  */
 static select_table_t *select_list = &select_core_table;
 
+/* the level of the select call that is beeing evaluated
+ * by the child process
+ */
+int select_level = 0;
+
 /*
  * Parse select string into select structure s
  * moves pointer p to the first unused char
@@ -274,7 +279,7 @@ int resolve_select(select_t* s)
                }
 
                if (t->table[table_idx].flags & FIXUP_CALL) {
-                       s->lvl = nested;
+                       select_level = nested;
                        s->param_offset[nested+1] = param_idx;
                        if (t->table[table_idx].new_f(NULL, s, NULL)<0) goto not_found;
                }
@@ -305,7 +310,7 @@ not_found:
 
 int run_select(str* res, select_t* s, struct sip_msg* msg)
 {
-       int ret;
+       int ret, orig_level;
 
        if (res == NULL) {
                BUG("Select unprepared result space\n");
@@ -321,10 +326,17 @@ int run_select(str* res, select_t* s, struct sip_msg* msg)
        }
        DBG("Calling SELECT %p \n", s->f);
 
+       /* save and resore the original select_level
+        * because of the nested selets */
+       orig_level = select_level;
        ret = 0;
-       for (s->lvl=0; (ret == 0) && (s->f[s->lvl] !=0 ) && (s->lvl<MAX_NESTED_CALLS); (s->lvl)++)      {
-               ret = s->f[s->lvl](res, s, msg);
+       for (   select_level=0;
+               (ret == 0) && (s->f[select_level] !=0 ) && (select_level<MAX_NESTED_CALLS);
+               select_level++
+       ) {
+               ret = s->f[select_level](res, s, msg);
        }
+       select_level = orig_level;
        return ret;
 }
 
index 1086daf..8d2051f 100644 (file)
--- a/select.h
+++ b/select.h
@@ -122,7 +122,6 @@ typedef struct select {
        int param_offset[MAX_NESTED_CALLS+1];
        select_param_t params[MAX_SELECT_PARAMS];
        int n;
-       int lvl;
 } select_t;
 
 typedef struct {
@@ -138,6 +137,11 @@ typedef struct select_table {
   struct select_table *next;
 } select_table_t;
 
+/* the level of the select call that is beeing evaluated
+ * by the child process
+ */
+extern int select_level;
+
 /*
  * Lookup corresponding select function based on
  * the select parameters
index 5022651..4a21d04 100644 (file)
@@ -547,7 +547,7 @@ int select_anyheader(str* res, select_t* s, struct sip_msg* msg)
        hf0 = NULL;
 
        /* extract header index if present */
-       if (s->param_offset[s->lvl+1] == 4) {
+       if (s->param_offset[select_level+1] == 4) {
                if (s->params[3].type == SEL_PARAM_INT) {
                        hi = s->params[3].v.i;
                } else {
@@ -698,7 +698,7 @@ int select_uri_params(str* res, select_t* s, struct sip_msg* msg)
        if (parse_uri(res->s, res->len, &uri)<0)
                return -1;
        
-       if (s->param_offset[s->lvl+1]-s->param_offset[s->lvl]==1)
+       if (s->param_offset[select_level+1]-s->param_offset[select_level]==1)
                RETURN0_res(uri.params);
 
        *res=uri.params;
@@ -713,17 +713,17 @@ int select_any_params(str* res, select_t* s, struct sip_msg* msg)
        int i;
 
        if (!msg || !res) {
-               if (s->param_offset[s->lvl+1]-s->param_offset[s->lvl]==1) return 0;
-               if (s->params[s->param_offset[s->lvl]+1].type!=SEL_PARAM_STR) return -1;
-               wanted=&s->params[s->param_offset[s->lvl]+1].v.s;
+               if (s->param_offset[select_level+1]-s->param_offset[select_level]==1) return 0;
+               if (s->params[s->param_offset[select_level]+1].type!=SEL_PARAM_STR) return -1;
+               wanted=&s->params[s->param_offset[select_level]+1].v.s;
                for (i=0; i<wanted->len; i++) 
                        if (wanted->s[i]=='_') 
                                wanted->s[i]='-';
                return 0;
        }
        
-       if (s->params[s->param_offset[s->lvl]+1].type!=SEL_PARAM_STR) return -1;
-       wanted=&s->params[s->param_offset[s->lvl]+1].v.s;
+       if (s->params[s->param_offset[select_level]+1].type!=SEL_PARAM_STR) return -1;
+       wanted=&s->params[s->param_offset[select_level]+1].v.s;
        
        if (!res->len) return -1;
        if (parse_params(res, CLASS_ANY, &h, &list)<0) return -1;
@@ -1071,7 +1071,7 @@ int select_nameaddr_params(str* res, select_t* s, struct sip_msg* msg)
        res->len=res->len - (p-res->s) -1;
        res->s=p +1;
        
-       if (s->param_offset[s->lvl+1]-s->param_offset[s->lvl]==1)
+       if (s->param_offset[select_level+1]-s->param_offset[select_level]==1)
                return (res->len ? 0 : 1);
 
        return select_any_params(res, s, msg);