Mercurial > hg > freeDiameter
comparison libfdcore/p_sr.c @ 1207:043b894b0511
Cleanups in failover situation to avoid deadlocks and corrupt messages ids. Tested OK now.
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Fri, 14 Jun 2013 17:30:42 +0800 |
parents | f40de74bd1c7 |
children | 9e92fa478c23 |
comparison
equal
deleted
inserted
replaced
1206:ef7c5e39badf | 1207:043b894b0511 |
---|---|
35 | 35 |
36 #include "fdcore-internal.h" | 36 #include "fdcore-internal.h" |
37 | 37 |
38 /* Structure to store a sent request */ | 38 /* Structure to store a sent request */ |
39 struct sentreq { | 39 struct sentreq { |
40 struct fd_list chain; /* the "o" field points directly to the hop-by-hop of the request (uint32_t *) */ | 40 struct fd_list chain; /* the "o" field points directly to the (new) hop-by-hop of the request (uint32_t *) */ |
41 struct msg *req; /* A request that was sent and not yet answered. */ | 41 struct msg *req; /* A request that was sent and not yet answered. */ |
42 uint32_t prevhbh;/* The value to set in the hbh header when the message is retrieved */ | 42 uint32_t prevhbh;/* The value to set back in the hbh header when the message is retrieved */ |
43 struct fd_list expire; /* the list of expiring requests */ | 43 struct fd_list expire; /* the list of expiring requests */ |
44 struct timespec added_on; /* the time the request was added */ | 44 struct timespec added_on; /* the time the request was added */ |
45 }; | 45 }; |
46 | 46 |
47 /* Find an element in the hbh list, or the following one */ | 47 /* Find an element in the hbh list, or the following one */ |
63 static void srl_dump(const char * text, struct fd_list * srlist) | 63 static void srl_dump(const char * text, struct fd_list * srlist) |
64 { | 64 { |
65 struct fd_list * li; | 65 struct fd_list * li; |
66 struct timespec now; | 66 struct timespec now; |
67 | 67 |
68 if (!TRACE_BOOL(ANNOYING)) | 68 LOG_D("%sSentReq list @%p:", text, srlist); |
69 return; | |
70 | |
71 fd_log_debug("%sSentReq list @%p:", text, srlist); | |
72 | 69 |
73 CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), ); | 70 CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), ); |
74 | 71 |
75 for (li = srlist->next; li != srlist; li = li->next) { | 72 for (li = srlist->next; li != srlist; li = li->next) { |
76 struct sentreq * sr = (struct sentreq *)li; | 73 struct sentreq * sr = (struct sentreq *)li; |
77 uint32_t * nexthbh = li->o; | 74 uint32_t * nexthbh = li->o; |
78 | 75 |
79 fd_log_debug(" - Next req (hbh:%x): [since %ld.%06ld sec]", *nexthbh, | 76 LOG_D(" - Next req (hbh:0x%x, prev:0x%x): [since %ld.%06ld sec]", *nexthbh, sr->prevhbh, |
80 (long)((now.tv_nsec >= sr->added_on.tv_nsec) ? (now.tv_sec - sr->added_on.tv_sec) : (now.tv_sec - sr->added_on.tv_sec - 1)), | 77 (long)((now.tv_nsec >= sr->added_on.tv_nsec) ? (now.tv_sec - sr->added_on.tv_sec) : (now.tv_sec - sr->added_on.tv_sec - 1)), |
81 (long)((now.tv_nsec >= sr->added_on.tv_nsec) ? ((now.tv_nsec - sr->added_on.tv_nsec) / 1000) : ((now.tv_nsec - sr->added_on.tv_nsec + 1000000000) / 1000))); | 78 (long)((now.tv_nsec >= sr->added_on.tv_nsec) ? ((now.tv_nsec - sr->added_on.tv_nsec) / 1000) : ((now.tv_nsec - sr->added_on.tv_nsec + 1000000000) / 1000))); |
82 } | 79 } |
83 } | 80 } |
84 | 81 |
222 | 219 |
223 /* Search the place in the list */ | 220 /* Search the place in the list */ |
224 CHECK_POSIX( pthread_mutex_lock(&srlist->mtx) ); | 221 CHECK_POSIX( pthread_mutex_lock(&srlist->mtx) ); |
225 next = find_or_next(&srlist->srs, *hbhloc, &match); | 222 next = find_or_next(&srlist->srs, *hbhloc, &match); |
226 if (match) { | 223 if (match) { |
227 TRACE_DEBUG(INFO, "A request with the same hop-by-hop Id was already sent: error"); | 224 TRACE_DEBUG(INFO, "A request with the same hop-by-hop Id (0x%x) was already sent: error", *hbhloc); |
228 free(sr); | 225 free(sr); |
226 srl_dump("Current list of SR: ", &srlist->srs); | |
229 CHECK_POSIX_DO( pthread_mutex_unlock(&srlist->mtx), /* ignore */ ); | 227 CHECK_POSIX_DO( pthread_mutex_unlock(&srlist->mtx), /* ignore */ ); |
230 return EINVAL; | 228 return EINVAL; |
231 } | 229 } |
232 | 230 |
233 /* Save in the list */ | 231 /* Save in the list */ |
234 *req = NULL; | 232 *req = NULL; |
235 fd_list_insert_before(next, &sr->chain); | 233 fd_list_insert_before(next, &sr->chain); |
236 srlist->cnt++; | 234 srlist->cnt++; |
237 srl_dump("Saved new request, ", &srlist->srs); | |
238 | 235 |
239 /* In case of request with a timeout, also store in the timeout list */ | 236 /* In case of request with a timeout, also store in the timeout list */ |
240 ts = fd_msg_anscb_gettimeout( sr->req ); | 237 ts = fd_msg_anscb_gettimeout( sr->req ); |
241 if (ts) { | 238 if (ts) { |
242 struct fd_list * li; | 239 struct fd_list * li; |
277 TRACE_ENTRY("%p %x %p", srlist, hbh, req); | 274 TRACE_ENTRY("%p %x %p", srlist, hbh, req); |
278 CHECK_PARAMS(srlist && req); | 275 CHECK_PARAMS(srlist && req); |
279 | 276 |
280 /* Search the request in the list */ | 277 /* Search the request in the list */ |
281 CHECK_POSIX( pthread_mutex_lock(&srlist->mtx) ); | 278 CHECK_POSIX( pthread_mutex_lock(&srlist->mtx) ); |
282 srl_dump("Fetching a request, ", &srlist->srs); | |
283 sr = (struct sentreq *)find_or_next(&srlist->srs, hbh, &match); | 279 sr = (struct sentreq *)find_or_next(&srlist->srs, hbh, &match); |
284 if (!match) { | 280 if (!match) { |
285 TRACE_DEBUG(INFO, "There is no saved request with this hop-by-hop id (%x)", hbh); | 281 TRACE_DEBUG(INFO, "There is no saved request with this hop-by-hop id (%x)", hbh); |
282 srl_dump("Current list of SR: ", &srlist->srs); | |
286 *req = NULL; | 283 *req = NULL; |
287 } else { | 284 } else { |
288 /* Restore hop-by-hop id */ | 285 /* Restore hop-by-hop id */ |
289 *((uint32_t *)sr->chain.o) = sr->prevhbh; | 286 *((uint32_t *)sr->chain.o) = sr->prevhbh; |
290 /* Unlink */ | 287 /* Unlink */ |