This is called by the Redis internals every time we want to fire an * event that can be interceppted by some module. The pointer 'data' is useful * in order to populate the event-specific structure when needed, in order * to return the structure with more information to the callback. * * 'eid' and 'subid' are just the main event ID and the sub event associated * with the event, depending on
| 8260 | * 'eid' and 'subid' are just the main event ID and the sub event associated |
| 8261 | * with the event, depending on what exactly happened. */ |
| 8262 | void moduleFireServerEvent(uint64_t eid, int subid, void *data) { |
| 8263 | /* Fast path to return ASAP if there is nothing to do, avoiding to |
| 8264 | * setup the iterator and so forth: we want this call to be extremely |
| 8265 | * cheap if there are no registered modules. */ |
| 8266 | if (listLength(RedisModule_EventListeners) == 0) return; |
| 8267 | |
| 8268 | int real_client_used = 0; |
| 8269 | listIter li; |
| 8270 | listNode *ln; |
| 8271 | listRewind(RedisModule_EventListeners,&li); |
| 8272 | while((ln = listNext(&li))) { |
| 8273 | RedisModuleEventListener *el = ln->value; |
| 8274 | if (el->event.id == eid) { |
| 8275 | RedisModuleCtx ctx = REDISMODULE_CTX_INIT; |
| 8276 | ctx.module = el->module; |
| 8277 | |
| 8278 | if (eid == REDISMODULE_EVENT_CLIENT_CHANGE) { |
| 8279 | /* In the case of client changes, we're pushing the real client |
| 8280 | * so the event handler can mutate it if needed. For example, |
| 8281 | * to change its authentication state in a way that does not |
| 8282 | * depend on specific commands executed later. |
| 8283 | */ |
| 8284 | ctx.client = (client *) data; |
| 8285 | real_client_used = 1; |
| 8286 | } else if (ModulesInHooks == 0) { |
| 8287 | ctx.client = moduleFreeContextReusedClient; |
| 8288 | } else { |
| 8289 | ctx.client = createClient(NULL); |
| 8290 | ctx.client->flags |= CLIENT_MODULE; |
| 8291 | ctx.client->user = NULL; /* Root user. */ |
| 8292 | } |
| 8293 | |
| 8294 | void *moduledata = NULL; |
| 8295 | RedisModuleClientInfoV1 civ1; |
| 8296 | RedisModuleReplicationInfoV1 riv1; |
| 8297 | RedisModuleModuleChangeV1 mcv1; |
| 8298 | /* Start at DB zero by default when calling the handler. It's |
| 8299 | * up to the specific event setup to change it when it makes |
| 8300 | * sense. For instance for FLUSHDB events we select the correct |
| 8301 | * DB automatically. */ |
| 8302 | selectDb(ctx.client, 0); |
| 8303 | |
| 8304 | /* Event specific context and data pointer setup. */ |
| 8305 | if (eid == REDISMODULE_EVENT_CLIENT_CHANGE) { |
| 8306 | modulePopulateClientInfoStructure(&civ1,data, |
| 8307 | el->event.dataver); |
| 8308 | moduledata = &civ1; |
| 8309 | } else if (eid == REDISMODULE_EVENT_REPLICATION_ROLE_CHANGED) { |
| 8310 | modulePopulateReplicationInfoStructure(&riv1,el->event.dataver); |
| 8311 | moduledata = &riv1; |
| 8312 | } else if (eid == REDISMODULE_EVENT_FLUSHDB) { |
| 8313 | moduledata = data; |
| 8314 | RedisModuleFlushInfoV1 *fi = data; |
| 8315 | if (fi->dbnum != -1) |
| 8316 | selectDb(ctx.client, fi->dbnum); |
| 8317 | } else if (eid == REDISMODULE_EVENT_MODULE_CHANGE) { |
| 8318 | RedisModule *m = data; |
| 8319 | if (m == el->module) |
no test coverage detected