Return a context which can be used inside threads to make Redis context * calls with certain modules APIs. If 'bc' is not NULL then the module will * be bound to a blocked client, and it will be possible to use the * `RedisModule_Reply*` family of functions to accumulate a reply for when the * client will be unblocked. Otherwise the thread safe context will be * detached by a specific client.
| 5886 | * consider using `RM_GetDetachedThreadSafeContext` which will also retain |
| 5887 | * the module ID and thus be more useful for logging. */ |
| 5888 | RedisModuleCtx *RM_GetThreadSafeContext(RedisModuleBlockedClient *bc) { |
| 5889 | RedisModuleCtx *ctx = (RedisModuleCtx*)zmalloc(sizeof(*ctx), MALLOC_LOCAL); |
| 5890 | RedisModuleCtx empty = REDISMODULE_CTX_INIT; |
| 5891 | memcpy(ctx,&empty,sizeof(empty)); |
| 5892 | if (bc) { |
| 5893 | ctx->blocked_client = bc; |
| 5894 | ctx->module = bc->module; |
| 5895 | } |
| 5896 | ctx->flags |= REDISMODULE_CTX_THREAD_SAFE; |
| 5897 | /* Even when the context is associated with a blocked client, we can't |
| 5898 | * access it safely from another thread, so we create a fake client here |
| 5899 | * in order to keep things like the currently selected database and similar |
| 5900 | * things. */ |
| 5901 | ctx->client = createClient(NULL, IDX_EVENT_LOOP_MAIN); |
| 5902 | if (bc) { |
| 5903 | selectDb(ctx->client,bc->dbid); |
| 5904 | if (bc->client) ctx->client->id = bc->client->id; |
| 5905 | } |
| 5906 | return ctx; |
| 5907 | } |
| 5908 | |
| 5909 | /* Return a detached thread safe context that is not associated with any |
| 5910 | * specific blocked client, but is associated with the module's context. |
nothing calls this directly
no test coverage detected