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 */
"Welcome to our mercurial repository"