浏览代码

Level of the select call is moved to a global variable form the structure
in order to make the select calls shared memory-safe.
Fixes SER-318

Miklos Tirpak 18 年之前
父节点
当前提交
559cb45747
共有 3 个文件被更改,包括 29 次插入13 次删除
  1. 16 4
      select.c
  2. 5 1
      select.h
  3. 8 8
      select_core.c

+ 16 - 4
select.c

@@ -55,6 +55,11 @@
  */
 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;
 }
 

+ 5 - 1
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

+ 8 - 8
select_core.c

@@ -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);