This is called from blocked.c in order to unblock a client: may be called * for multiple reasons while the client is in the middle of being blocked * because the client is terminated, but is also called for cleanup when a * client is unblocked in a clean way after replaying. * * What we do here is just to set the client to NULL in the redis module * blocked client handle. This way if the cli
| 5224 | * The structure RedisModuleBlockedClient will be always deallocated when |
| 5225 | * running the list of clients blocked by a module that need to be unblocked. */ |
| 5226 | void unblockClientFromModule(client *c) { |
| 5227 | RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle; |
| 5228 | |
| 5229 | /* Call the disconnection callback if any. Note that |
| 5230 | * bc->disconnect_callback is set to NULL if the client gets disconnected |
| 5231 | * by the module itself or because of a timeout, so the callback will NOT |
| 5232 | * get called if this is not an actual disconnection event. */ |
| 5233 | if (bc->disconnect_callback) { |
| 5234 | RedisModuleCtx ctx = REDISMODULE_CTX_INIT; |
| 5235 | ctx.blocked_privdata = bc->privdata; |
| 5236 | ctx.module = bc->module; |
| 5237 | ctx.client = bc->client; |
| 5238 | bc->disconnect_callback(&ctx,bc); |
| 5239 | moduleFreeContext(&ctx); |
| 5240 | } |
| 5241 | |
| 5242 | /* If we made it here and client is still blocked it means that the command |
| 5243 | * timed-out, client was killed or disconnected and disconnect_callback was |
| 5244 | * not implemented (or it was, but RM_UnblockClient was not called from |
| 5245 | * within it, as it should). |
| 5246 | * We must call moduleUnblockClient in order to free privdata and |
| 5247 | * RedisModuleBlockedClient. |
| 5248 | * |
| 5249 | * Note that we only do that for clients that are blocked on keys, for which |
| 5250 | * the contract is that the module should not call RM_UnblockClient under |
| 5251 | * normal circumstances. |
| 5252 | * Clients implementing threads and working with private data should be |
| 5253 | * aware that calling RM_UnblockClient for every blocked client is their |
| 5254 | * responsibility, and if they fail to do so memory may leak. Ideally they |
| 5255 | * should implement the disconnect and timeout callbacks and call |
| 5256 | * RM_UnblockClient, but any other way is also acceptable. */ |
| 5257 | if (bc->blocked_on_keys && !bc->unblocked) |
| 5258 | moduleUnblockClient(c); |
| 5259 | |
| 5260 | bc->client = NULL; |
| 5261 | } |
| 5262 | |
| 5263 | /* Block a client in the context of a module: this function implements both |
| 5264 | * RM_BlockClient() and RM_BlockClientOnKeys() depending on the fact the |
no test coverage detected