1. res_config_mysql的模块加载早于chan_sip,他们的加载函数均为load_module
先分析res_config_mysql的load_module函数
     
 
parse_config(0);
parse_config解析res_config_mysql文件,并用文件中的配置信息填充mysql_conn结构体
我当前的res_config_mysql文件如下
[general]
dbhost = 192.168.1.182
dbname = asterisk
dbuser = root
dbpass = 123456
dbport = 3306
解析完成后,mysql_conn里面会得到这些数据struct mysql_conn {
     AST_RWLIST_ENTRY(mysql_conn) list;
     ast_mutex_t    lock;
     MYSQL       handle;
     char        host[50];                192.168.1.182
     char        name[50];              asterisk
     char        user[50];                root
     char        pass[50];               123456
     char        sock[50];
     char        charset[50];
     int         port;                         3306
     int         connected;
     time_t      connect_time;
     enum requirements requirements;
     char        unique_name[0];
 };
 
     ast_config_engine_register(&mysql_engine);
将res_config_mysql这个模块的函数结构体注册到
static struct ast_config_engine *config_engine_list;
 
实际res_config_mysql的load_module函数完成两个事情,解析res_config_mysql.conf配置文件,并存储。
然后向系统注册res_config_mysql的功能函数
 
 
 
2. chan_sip模块的加载
chan_sip模块的加载也是load_module函数,在这个函数中我们主要关注reload_config函数
在reload_config函数中调用
    cfg = ast_config_load(config, config_flags);  config为sip.conf
 
但是这里ast_config_load并不是直接加载sip.conf文件来生成一个ast_config结构体的。
我们将其展开来分析,ast_config_load最终是调用了ast_config_internal_load
 
3. ast_config_internal_load分析
 
if (!ast_test_flag(&flags, CONFIG_FLAG_NOREALTIME) && config_engine_list) {
         flags是0,并且res_config_mysql模块将其函数注册到了config_engine_list中,因此if语句为真
 
         struct ast_config_engine *eng;
       从下面find_engine的分析,eng将得到res_config_mysql的ast_config_engine结构体
         eng = find_engine(filename, 1, db, sizeof(db), table, sizeof(table));
 
 
         if (eng && eng->load_func) {
             loader = eng;
         } else {
             eng = find_engine("global", 1, db, sizeof(db), table, sizeof(table));
             if (eng && eng->load_func)
                 loader = eng;
         }
     }
         最后调用了res_config_mysql的oad_func函数,即config_mysql函数
 
         result = loader->load_func(db, table, filename, cfg, flags, suggested_include_file, who_asked);
 
 4. find_engine分析
 
find_engine展开解释,在extconfig.conf被解析后,config_maps里面如下
name = extensions dirver =mysql database =general table =extensions
name = sip.conf dirver =mysql database =general table =sip_config2
for (map = config_maps; map; map = map->next) {
        family为"sip.conf",因此,for结束后,database = general, table = sip_config2
 
         if (!strcasecmp(family, map->name) && (priority == map->priority)) {
             if (database)
                 ast_copy_string(database, map->database, dbsiz);
             if (table)
                 ast_copy_string(table, map->table ? map->table : family, tabsiz);
             break;
         }
     }
 
     /* Check if the required driver (engine) exist */
     if (map) {
从res_config_mysql看他的ast_config_engine的定义里面,其name为mysql,从上面看map的driver也是mysql,
    因此 find_engine这个函数最后返回了res_config_mysql这个ast_config_engine
 
        for (eng = config_engine_list; !ret && eng; eng = eng->next) {
             if (!strcasecmp(eng->name, map->driver))
                 ret = eng;
         }
     }