Unblock a client calling the right function depending on the kind * of operation the client is blocking for. */
| 177 | /* Unblock a client calling the right function depending on the kind |
| 178 | * of operation the client is blocking for. */ |
| 179 | void unblockClient(client *c) { |
| 180 | if (c->btype == BLOCKED_LIST || |
| 181 | c->btype == BLOCKED_ZSET || |
| 182 | c->btype == BLOCKED_STREAM) { |
| 183 | unblockClientWaitingData(c); |
| 184 | } else if (c->btype == BLOCKED_WAIT) { |
| 185 | unblockClientWaitingReplicas(c); |
| 186 | } else if (c->btype == BLOCKED_MODULE) { |
| 187 | if (moduleClientIsBlockedOnKeys(c)) unblockClientWaitingData(c); |
| 188 | unblockClientFromModule(c); |
| 189 | } else if (c->btype == BLOCKED_PAUSE) { |
| 190 | listDelNode(server.paused_clients,c->paused_list_node); |
| 191 | c->paused_list_node = NULL; |
| 192 | } else { |
| 193 | serverPanic("Unknown btype in unblockClient()."); |
| 194 | } |
| 195 | |
| 196 | /* Reset the client for a new query since, for blocking commands |
| 197 | * we do not do it immediately after the command returns (when the |
| 198 | * client got blocked) in order to be still able to access the argument |
| 199 | * vector from module callbacks and updateStatsOnUnblock. */ |
| 200 | if (c->btype != BLOCKED_PAUSE) { |
| 201 | freeClientOriginalArgv(c); |
| 202 | resetClient(c); |
| 203 | } |
| 204 | |
| 205 | /* Clear the flags, and put the client in the unblocked list so that |
| 206 | * we'll process new commands in its query buffer ASAP. */ |
| 207 | server.blocked_clients--; |
| 208 | server.blocked_clients_by_type[c->btype]--; |
| 209 | c->flags &= ~CLIENT_BLOCKED; |
| 210 | c->btype = BLOCKED_NONE; |
| 211 | removeClientFromTimeoutTable(c); |
| 212 | queueClientForReprocessing(c); |
| 213 | } |
| 214 | |
| 215 | /* This function gets called when a blocked client timed out in order to |
| 216 | * send it a reply of some kind. After this function is called, |
no test coverage detected