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
| 5333 | * The structure RedisModuleBlockedClient will be always deallocated when |
| 5334 | * running the list of clients blocked by a module that need to be unblocked. */ |
| 5335 | void unblockClientFromModule(client *c) { |
| 5336 | RedisModuleBlockedClient *bc = (RedisModuleBlockedClient*)c->bpop.module_blocked_handle; |
| 5337 | |
| 5338 | /* Call the disconnection callback if any. Note that |
| 5339 | * bc->disconnect_callback is set to NULL if the client gets disconnected |
| 5340 | * by the module itself or because of a timeout, so the callback will NOT |
| 5341 | * get called if this is not an actual disconnection event. */ |
| 5342 | if (bc->disconnect_callback) { |
| 5343 | RedisModuleCtx ctx = REDISMODULE_CTX_INIT; |
| 5344 | ctx.blocked_privdata = bc->privdata; |
| 5345 | ctx.module = bc->module; |
| 5346 | ctx.client = bc->client; |
| 5347 | bc->disconnect_callback(&ctx,bc); |
| 5348 | moduleFreeContext(&ctx); |
| 5349 | } |
| 5350 | |
| 5351 | /* If we made it here and client is still blocked it means that the command |
| 5352 | * timed-out, client was killed or disconnected and disconnect_callback was |
| 5353 | * not implemented (or it was, but RM_UnblockClient was not called from |
| 5354 | * within it, as it should). |
| 5355 | * We must call moduleUnblockClient in order to free privdata and |
| 5356 | * RedisModuleBlockedClient. |
| 5357 | * |
| 5358 | * Note that we only do that for clients that are blocked on keys, for which |
| 5359 | * the contract is that the module should not call RM_UnblockClient under |
| 5360 | * normal circumstances. |
| 5361 | * Clients implementing threads and working with private data should be |
| 5362 | * aware that calling RM_UnblockClient for every blocked client is their |
| 5363 | * responsibility, and if they fail to do so memory may leak. Ideally they |
| 5364 | * should implement the disconnect and timeout callbacks and call |
| 5365 | * RM_UnblockClient, but any other way is also acceptable. */ |
| 5366 | if (bc->blocked_on_keys && !bc->unblocked) |
| 5367 | moduleUnblockClient(c); |
| 5368 | |
| 5369 | bc->client = NULL; |
| 5370 | } |
| 5371 | |
| 5372 | /* Block a client in the context of a module: this function implements both |
| 5373 | * RM_BlockClient() and RM_BlockClientOnKeys() depending on the fact the |
no test coverage detected