Decrement the refcount of a link object, if it drops to zero, actually * free it and return NULL. Otherwise don't do anything and return the pointer * to the object. * * If we are not going to free the link and ri is not NULL, we rebind all the * pending requests in link->cc (hiredis connection for commands) to a * callback that will just ignore them. This is useful to avoid processing * re
| 1086 | * callback that will just ignore them. This is useful to avoid processing |
| 1087 | * replies for an instance that no longer exists. */ |
| 1088 | instanceLink *releaseInstanceLink(instanceLink *link, sentinelRedisInstance *ri) |
| 1089 | { |
| 1090 | serverAssert(link->refcount > 0); |
| 1091 | link->refcount--; |
| 1092 | if (link->refcount != 0) { |
| 1093 | if (ri && ri->link->cc) { |
| 1094 | /* This instance may have pending callbacks in the hiredis async |
| 1095 | * context, having as 'privdata' the instance that we are going to |
| 1096 | * free. Let's rewrite the callback list, directly exploiting |
| 1097 | * hiredis internal data structures, in order to bind them with |
| 1098 | * a callback that will ignore the reply at all. */ |
| 1099 | redisCallback *cb; |
| 1100 | redisCallbackList *callbacks = &link->cc->replies; |
| 1101 | |
| 1102 | cb = callbacks->head; |
| 1103 | while(cb) { |
| 1104 | if (cb->privdata == ri) { |
| 1105 | cb->fn = sentinelDiscardReplyCallback; |
| 1106 | cb->privdata = NULL; /* Not strictly needed. */ |
| 1107 | } |
| 1108 | cb = cb->next; |
| 1109 | } |
| 1110 | } |
| 1111 | return link; /* Other active users. */ |
| 1112 | } |
| 1113 | |
| 1114 | instanceLinkCloseConnection(link,link->cc); |
| 1115 | instanceLinkCloseConnection(link,link->pc); |
| 1116 | zfree(link); |
| 1117 | return NULL; |
| 1118 | } |
| 1119 | |
| 1120 | /* This function will attempt to share the instance link we already have |
| 1121 | * for the same Sentinel in the context of a different master, with the |
no test coverage detected