通上面的函數就可以把服務和事件觸發的命令添加隊列裡。其實是在文件parser.c頭部,就聲明瞭下面三個鏈表,如下:
static list_declare(service_list);
static list_declare(action_list);
static list_declare(action_queue);
service_list是定義添加分析所有資源文件裡的服務,action_list是定義添加分析所有資源文件裡的事件觸發的命令列表,action_queue是定義添加當前需要執行操作的命令動作或者服務等。
那麼又有下面一個問題瞭,init進程是在那裡添加這些服務或命令到運行隊列呢?在init.c文件看到下面的代碼:
action_for_each_trigger(“early-init”, action_add_queue_tail);
drain_action_queue();
原來是通過函數action_for_each_trigger來把所有需要按事件觸發運行的命令添加到隊列裡,函數action_add_queue_tail把需要執行命令放到隊列,函數drain_action_queue把添加到隊列裡的命令進行運行。
#001 void action_for_each_trigger(const char *trigger,
#002 void (*func)(struct action *act))
#003 {
#004 struct listnode *node;
#005 struct action *act;
#006 list_for_each(node, &action_list) {
這行代碼是遍歷鏈表所有項。
#007 act = node_to_item(node, struct action, alist);
這行代碼是把動作節點轉換為動作項。
#008 if (!strcmp(act->name, trigger)) {
#009 func(act);
這段代碼是當找到與用戶輸入相同事件觸發的動作,比如上面是查找“early-init”事件。這時就把動作項添加到將要運行的隊列裡。
#010 }
#011 }
#012 }