mirror of https://github.com/redis/redis.git
				
				
				
			Modules hooks: handle module unloading + API export.
This commit is contained in:
		
							parent
							
								
									1e78681df8
								
							
						
					
					
						commit
						d54652682d
					
				
							
								
								
									
										27
									
								
								src/module.c
								
								
								
								
							
							
						
						
									
										27
									
								
								src/module.c
								
								
								
								
							| 
						 | 
					@ -5708,7 +5708,7 @@ void ModuleForkDoneHandler(int exitcode, int bysignal) {
 | 
				
			||||||
 * The function returns REDISMODULE_OK if the module was successfully subscrived
 | 
					 * The function returns REDISMODULE_OK if the module was successfully subscrived
 | 
				
			||||||
 * for the specified event. If the API is called from a wrong context then
 | 
					 * for the specified event. If the API is called from a wrong context then
 | 
				
			||||||
 * REDISMODULE_ERR is returned. */
 | 
					 * REDISMODULE_ERR is returned. */
 | 
				
			||||||
int RedisModule_SubscribeToServerEvent(RedisModuleCtx *ctx, RedisModuleEvent event, RedisModuleEventCallback callback) {
 | 
					int RM_SubscribeToServerEvent(RedisModuleCtx *ctx, RedisModuleEvent event, RedisModuleEventCallback callback) {
 | 
				
			||||||
    RedisModuleEventListener *el;
 | 
					    RedisModuleEventListener *el;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Protect in case of calls from contexts without a module reference. */
 | 
					    /* Protect in case of calls from contexts without a module reference. */
 | 
				
			||||||
| 
						 | 
					@ -5751,7 +5751,7 @@ int RedisModule_SubscribeToServerEvent(RedisModuleCtx *ctx, RedisModuleEvent eve
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * 'eid' and 'subid' are just the main event ID and the sub event associated
 | 
					 * 'eid' and 'subid' are just the main event ID and the sub event associated
 | 
				
			||||||
 * with the event, depending on what exactly happened. */
 | 
					 * with the event, depending on what exactly happened. */
 | 
				
			||||||
void RedisModule_FireServerEvent(uint64_t eid, int subid, void *data) {
 | 
					void moduleFireServerEvent(uint64_t eid, int subid, void *data) {
 | 
				
			||||||
    /* Fast path to return ASAP if there is nothing to do, avoiding to
 | 
					    /* Fast path to return ASAP if there is nothing to do, avoiding to
 | 
				
			||||||
     * setup the iterator and so forth: we want this call to be extremely
 | 
					     * setup the iterator and so forth: we want this call to be extremely
 | 
				
			||||||
     * cheap if there are no registered modules. */
 | 
					     * cheap if there are no registered modules. */
 | 
				
			||||||
| 
						 | 
					@ -5779,6 +5779,23 @@ void RedisModule_FireServerEvent(uint64_t eid, int subid, void *data) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Remove all the listeners for this module: this is used before unloading
 | 
				
			||||||
 | 
					 * a module. */
 | 
				
			||||||
 | 
					void moduleUnsubscribeAllServerEvents(RedisModule *module) {
 | 
				
			||||||
 | 
					    RedisModuleEventListener *el;
 | 
				
			||||||
 | 
					    listIter li;
 | 
				
			||||||
 | 
					    listNode *ln;
 | 
				
			||||||
 | 
					    listRewind(RedisModule_EventListeners,&li);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while((ln = listNext(&li))) {
 | 
				
			||||||
 | 
					        el = ln->value;
 | 
				
			||||||
 | 
					        if (el->module == module) {
 | 
				
			||||||
 | 
					            listDelNode(RedisModule_EventListeners,ln);
 | 
				
			||||||
 | 
					            zfree(el);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* --------------------------------------------------------------------------
 | 
					/* --------------------------------------------------------------------------
 | 
				
			||||||
 * Modules API internals
 | 
					 * Modules API internals
 | 
				
			||||||
 * -------------------------------------------------------------------------- */
 | 
					 * -------------------------------------------------------------------------- */
 | 
				
			||||||
| 
						 | 
					@ -5970,7 +5987,7 @@ int moduleUnload(sds name) {
 | 
				
			||||||
        errno = EPERM;
 | 
					        errno = EPERM;
 | 
				
			||||||
        return REDISMODULE_ERR;
 | 
					        return REDISMODULE_ERR;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    /* Give module a chance to clean up. */
 | 
					    /* Give module a chance to clean up. */
 | 
				
			||||||
    int (*onunload)(void *);
 | 
					    int (*onunload)(void *);
 | 
				
			||||||
    onunload = (int (*)(void *))(unsigned long) dlsym(module->handle, "RedisModule_OnUnload");
 | 
					    onunload = (int (*)(void *))(unsigned long) dlsym(module->handle, "RedisModule_OnUnload");
 | 
				
			||||||
| 
						 | 
					@ -5995,8 +6012,7 @@ int moduleUnload(sds name) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Remove any notification subscribers this module might have */
 | 
					    /* Remove any notification subscribers this module might have */
 | 
				
			||||||
    moduleUnsubscribeNotifications(module);
 | 
					    moduleUnsubscribeNotifications(module);
 | 
				
			||||||
 | 
					    moduleUnsubscribeAllServerEvents(module);
 | 
				
			||||||
    /* Unregister all the hooks. TODO: Yet no hooks support here. */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Unload the dynamic library. */
 | 
					    /* Unload the dynamic library. */
 | 
				
			||||||
    if (dlclose(module->handle) == -1) {
 | 
					    if (dlclose(module->handle) == -1) {
 | 
				
			||||||
| 
						 | 
					@ -6336,4 +6352,5 @@ void moduleRegisterCoreAPI(void) {
 | 
				
			||||||
    REGISTER_API(InfoAddFieldLongLong);
 | 
					    REGISTER_API(InfoAddFieldLongLong);
 | 
				
			||||||
    REGISTER_API(InfoAddFieldULongLong);
 | 
					    REGISTER_API(InfoAddFieldULongLong);
 | 
				
			||||||
    REGISTER_API(GetClientInfoById);
 | 
					    REGISTER_API(GetClientInfoById);
 | 
				
			||||||
 | 
					    REGISTER_API(SubscribeToServerEvent);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -446,6 +446,7 @@ int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldCString)(RedisModuleInfoCtx *ct
 | 
				
			||||||
int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldDouble)(RedisModuleInfoCtx *ctx, char *field, double value);
 | 
					int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldDouble)(RedisModuleInfoCtx *ctx, char *field, double value);
 | 
				
			||||||
int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldLongLong)(RedisModuleInfoCtx *ctx, char *field, long long value);
 | 
					int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldLongLong)(RedisModuleInfoCtx *ctx, char *field, long long value);
 | 
				
			||||||
int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldULongLong)(RedisModuleInfoCtx *ctx, char *field, unsigned long long value);
 | 
					int REDISMODULE_API_FUNC(RedisModule_InfoAddFieldULongLong)(RedisModuleInfoCtx *ctx, char *field, unsigned long long value);
 | 
				
			||||||
 | 
					int REDISMODULE_API_FUNC(RedisModule_SubscribeToServerEvent)(RedisModuleCtx *ctx, RedisModuleEvent event, RedisModuleEventCallback callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Experimental APIs */
 | 
					/* Experimental APIs */
 | 
				
			||||||
#ifdef REDISMODULE_EXPERIMENTAL_API
 | 
					#ifdef REDISMODULE_EXPERIMENTAL_API
 | 
				
			||||||
| 
						 | 
					@ -637,6 +638,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
 | 
				
			||||||
    REDISMODULE_GET_API(InfoAddFieldLongLong);
 | 
					    REDISMODULE_GET_API(InfoAddFieldLongLong);
 | 
				
			||||||
    REDISMODULE_GET_API(InfoAddFieldULongLong);
 | 
					    REDISMODULE_GET_API(InfoAddFieldULongLong);
 | 
				
			||||||
    REDISMODULE_GET_API(GetClientInfoById);
 | 
					    REDISMODULE_GET_API(GetClientInfoById);
 | 
				
			||||||
 | 
					    REDISMODULE_GET_API(SubscribeToServerEvent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef REDISMODULE_EXPERIMENTAL_API
 | 
					#ifdef REDISMODULE_EXPERIMENTAL_API
 | 
				
			||||||
    REDISMODULE_GET_API(GetThreadSafeContext);
 | 
					    REDISMODULE_GET_API(GetThreadSafeContext);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1598,6 +1598,7 @@ int TerminateModuleForkChild(int child_pid, int wait);
 | 
				
			||||||
ssize_t rdbSaveModulesAux(rio *rdb, int when);
 | 
					ssize_t rdbSaveModulesAux(rio *rdb, int when);
 | 
				
			||||||
int moduleAllDatatypesHandleErrors();
 | 
					int moduleAllDatatypesHandleErrors();
 | 
				
			||||||
sds modulesCollectInfo(sds info, sds section, int for_crash_report, int sections);
 | 
					sds modulesCollectInfo(sds info, sds section, int for_crash_report, int sections);
 | 
				
			||||||
 | 
					void moduleFireServerEvent(uint64_t eid, int subid, void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Utils */
 | 
					/* Utils */
 | 
				
			||||||
long long ustime(void);
 | 
					long long ustime(void);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue