3.7.2 event_init:初始化事件处理程序

来源:互联网 发布:知远的意思是什么 编辑:程序博客网 时间:2024/06/06 02:28

该函数的核心任务是初始化EVENT_ALLOC_INCR(默认为10)个EVENT_FDTABLE结构体,将EVENT_FDTABLE的callback和context项置0。然后将回调函数和相应的fd“绑定”起来。

 

EVENT_FDTABLE结构体本身不完成这个任务,因为结构体中的项是回调函数和上下文,没有fd。但EVENT_FDTABLE结构体是按照fd来索引的,我们以此完成fd和相应EVENT_FDTABLE结构体的绑定。

 

event_init函数只在events.c中的相关函数中被调用,且只初始化一次,因为我们在模块中只需要一个EVENT_FDTABLE结构体数组实例。

/util/event.c541 static void event_init(void) 542 { 543    EVENT_FDTABLE *fdp; 544    int     err; 545 546    if (!EVENT_INIT_NEEDED()) 547        msg_panic("event_init: repeated call");


 546-547 event_init函数只允许调用一次,也就是事件初始化只会执行一次。是否进行过初始化用能否取得当前的时间来判断。在595行,event_init函数快要执行完毕时,

将当前时间保存在event_present结构体中。所以,任何时候我们都可以通过查看event_present结构体来判断是否调用过event_init函数:如果该结构体位空,则还没有调用过event_init函数,否则已经调用过event_init函数。

event_present结构体定义如下:

static time_tevent_present;           /* cached time ofday */EVENT_INIT_NEEDED宏展开如下:#defineEVENT_INIT_NEEDED()      (event_present ==0)

548 549    /* 550     * Initialize the file descriptor masks and the call-back table. Where 551     * possible we extend these data structures on the fly. With select(2) 552     * based implementations we can only handle FD_SETSIZE open files. 553     */ 554 #if (EVENTS_STYLE == EVENTS_STYLE_SELECT) 555    if ((event_fdlimit = open_limit(FD_SETSIZE)) < 0)556        msg_fatal("unable to determine open file limit");557 #else558     if ((event_fdlimit =open_limit(INT_MAX)) < 0) 559        msg_fatal("unable to determine open file limit"); 560 #endif 561    if (event_fdlimit < FD_SETSIZE / 2 && event_fdlimit < 256) 562        msg_warn("could allocate space for only %d open files",event_fdlimit);

 

554-562 fd限制的判断与告警。

 

563     event_fdslots =EVENT_ALLOC_INCR; 564    event_fdtable = (EVENT_FDTABLE *) 565        mymalloc(sizeof(EVENT_FDTABLE) * event_fdslots); 566    for (fdp = event_fdtable; fdp < event_fdtable + event_fdslots; fdp++){ 567        fdp->callback = 0; 568        fdp->context = 0; 569     }

 

 563-569 初始化EVENT_ALLOC_INCR(默认为10)个EVENT_FDTABLE结构体,其字段被初始化为0。

570 571    /* 572     * Initialize the I/O event request masks. 573     */ 574 #if (EVENTS_STYLE == EVENTS_STYLE_SELECT) 575    EVENT_MASK_ZERO(&event_rmask); 576    EVENT_MASK_ZERO(&event_wmask); 577    EVENT_MASK_ZERO(&event_xmask); 578 #else 579    EVENT_MASK_ALLOC(&event_rmask, event_fdslots); 580    EVENT_MASK_ALLOC(&event_wmask, event_fdslots); 581    EVENT_MASK_ALLOC(&event_xmask, event_fdslots);582 583    /* 584     * Initialize the kernel-based filter. 585     */ 586    EVENT_REG_INIT_HANDLE(err, event_fdslots);587     if (err < 0) 588        msg_fatal("%s: %m", EVENT_REG_INIT_TEXT); 589 #endif

 574-589 多路复用函数相关设置。

 590 591    /* 592     * Initialize timer stuff. 593     */ 594    ring_init(&event_timer_head);

594初始化节点为event_timer_head的双向链表,我们用双向链表管理EVENT_TIMER结构体:

static RINGevent_timer_head;

 

 595    (void) time(&event_present);

 

595 初始化event_present:至此,凡检测到event_present不为0,则不能再运行event_init。同时,600-601的判断表示:如果event_init执行完毕,event_present还为0,意味着event_init执行失败。

 

 596 597    /* 598     * Avoid an infinite initialization loop. 599     */ 600    if (EVENT_INIT_NEEDED()) 601        msg_panic("event_init: unable to initialize"); 602 }

0 0
原创粉丝点击