Browse code

dispatcher: sync on updating last used fields

Daniel-Constantin Mierla authored on 14/09/2020 11:00:25
Showing 1 changed files
... ...
@@ -2070,6 +2070,7 @@ int ds_manage_routes(sip_msg_t *msg, ds_select_state_t *rstate)
2070 2070
 	unsigned int hash;
2071 2071
 	ds_set_t *idx = NULL;
2072 2072
 	int ulast = 0;
2073
+	int vlast = 0;
2073 2074
 
2074 2075
 	if(msg == NULL) {
2075 2076
 		LM_ERR("bad parameters\n");
... ...
@@ -2124,8 +2125,11 @@ int ds_manage_routes(sip_msg_t *msg, ds_select_state_t *rstate)
2124 2125
 			}
2125 2126
 			break;
2126 2127
 		case DS_ALG_ROUNDROBIN: /* 4 - round robin */
2128
+			lock_get(&idx->lock);
2127 2129
 			hash = idx->last;
2128 2130
 			idx->last = (idx->last + 1) % idx->nr;
2131
+			vlast = idx->last;
2132
+			lock_release(&idx->lock);
2129 2133
 			ulast = 1;
2130 2134
 			break;
2131 2135
 		case DS_ALG_HASHAUTHUSER: /* 5 - hash auth username */
... ...
@@ -2136,8 +2140,11 @@ int ds_manage_routes(sip_msg_t *msg, ds_select_state_t *rstate)
2136 2140
 					break;
2137 2141
 				case 1:
2138 2142
 					/* No Authorization found: Use round robin */
2143
+					lock_get(&idx->lock);
2139 2144
 					hash = idx->last;
2140 2145
 					idx->last = (idx->last + 1) % idx->nr;
2146
+					vlast = idx->last;
2147
+					lock_release(&idx->lock);
2141 2148
 					ulast = 1;
2142 2149
 					break;
2143 2150
 				default:
... ...
@@ -2158,8 +2165,10 @@ int ds_manage_routes(sip_msg_t *msg, ds_select_state_t *rstate)
2158 2165
 			hash = 0;
2159 2166
 			break;
2160 2167
 		case DS_ALG_WEIGHT: /* 9 - weight based distribution */
2168
+			lock_get(&idx->lock);
2161 2169
 			hash = idx->wlist[idx->wlast];
2162 2170
 			idx->wlast = (idx->wlast + 1) % 100;
2171
+			lock_release(&idx->lock);
2163 2172
 			break;
2164 2173
 		case DS_ALG_CALLLOAD: /* 10 - call load based distribution */
2165 2174
 			/* only INVITE can start a call */
... ...
@@ -2189,8 +2198,10 @@ int ds_manage_routes(sip_msg_t *msg, ds_select_state_t *rstate)
2189 2198
 			}
2190 2199
 			break;
2191 2200
 		case DS_ALG_RELWEIGHT: /* 11 - relative weight based distribution */
2201
+			lock_get(&idx->lock);
2192 2202
 			hash = idx->rwlist[idx->rwlast];
2193 2203
 			idx->rwlast = (idx->rwlast + 1) % 100;
2204
+			lock_release(&idx->lock);
2194 2205
 			break;
2195 2206
 		case DS_ALG_PARALLEL: /* 12 - parallel dispatching */
2196 2207
 			hash = 0;
... ...
@@ -2240,10 +2251,13 @@ int ds_manage_routes(sip_msg_t *msg, ds_select_state_t *rstate)
2240 2251
 		rstate->emode = 1;
2241 2252
 	}
2242 2253
 
2243
-	/* update last field for next select to point after the current active used */
2244
-	if(ulast) {
2254
+	/* update last field for next select to point after the current active used,
2255
+	 * if not updated meanwhile */
2256
+	lock_get(&idx->lock);
2257
+	if(ulast && (vlast == idx->last)) {
2245 2258
 		idx->last = (hash + 1) % idx->nr;
2246 2259
 	}
2260
+	lock_release(&idx->lock);
2247 2261
 
2248 2262
 	LM_DBG("selected [%d-%d-%d/%d] <%.*s>\n", rstate->alg, rstate->setid,
2249 2263
 			rstate->umode, hash,