FreeSwitch模块加载过程

        本文基于FreeSwitch V1.8.7分析。

        首先是模块接口定义:

        类型定义:

接口定义于\freeswitch-1.8.7\src\include\switch_types.h

typedef struct switch_loadable_module_function_table {
	int switch_api_version;
	switch_module_load_t load;
	switch_module_shutdown_t shutdown;
	switch_module_runtime_t runtime;
	switch_module_flag_t flags;
} switch_loadable_module_function_table_t;

同时提供以下宏作为用于定义模块:

#define SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime)								\
		SWITCH_MODULE_DEFINITION_EX(name, load, shutdown, runtime, SMODF_NONE)

      每一个模块都会在自己的实现文件中定义一个全局模块接口变量变量,如mod_sofia,结构变量中包含三个函数指针:load、shutdown和runtime。

SWITCH_MODULE_DEFINITION(mod_sofia, mod_sofia_load, mod_sofia_shutdown, NULL);

       FreeSwitch根据modules.conf.xml的配置加载模块。

FS加载模块是根据modules.conf.xml文件内容加载模块。以mod_sofia模块为例,FS读取(如Linux系统下调用dlopen函数读取)mod_sofia对象的地址,然后调用load函数,load函数会将APP/API接口加载到不同类别HASH表里。在以后调用模块接口时,根据APP或API的名称作为HASH的key定位,并调用APP或API函数。

        接口加载注册完成之后,检查模块是否有runtime函数,如果有调用switch_core_launch_thread()加载线程,线程函数入口为switch_loadable_module_exec,它循环调用runtime函数。

static void *SWITCH_THREAD_FUNC switch_loadable_module_exec(switch_thread_t *thread, void *obj)
{


	switch_status_t status = SWITCH_STATUS_SUCCESS;
	switch_core_thread_session_t *ts = obj;
	switch_loadable_module_t *module = ts->objs[0];
	int restarts;

	switch_assert(thread != NULL);
	switch_assert(module != NULL);

	for (restarts = 0; status != SWITCH_STATUS_TERM && !module->shutting_down; restarts++) {
		status = module->switch_module_runtime();
	}
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Thread ended for %s\n", module->module_interface->module_name);

	if (ts->pool) {
		switch_memory_pool_t *pool = ts->pool;
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Destroying Pool for %s\n", module->module_interface->module_name);
		switch_core_destroy_memory_pool(&pool);
	}
	switch_thread_exit(thread, 0);
	return NULL;
}

        当模块卸载时,会检查是否有shutdown函数,如果有调用它完成退出和释放资源。

流程图:

FreeSwitch模块加载过程_第1张图片

你可能感兴趣的:(FreeSWITCH)