libevent源码分析:evmap_io_active_函数
evmap_io_active_函数用于将激活指定文件描述符上的事件
1 void 2 evmap_io_active_(struct event_base *base, evutil_socket_t fd, short events) 3 { 4 struct event_io_map *io = &base->io; 5 struct evmap_io *ctx; 6 struct event *ev; 7 8 #ifndef EVMAP_USE_HT 9 if (fd < 0 || fd >= io->nentries) 10 return; 11 #endif 12 GET_IO_SLOT(ctx, io, fd, evmap_io); 13 14 if (NULL == ctx) 15 return; 16 LIST_FOREACH(ev, &ctx->events, ev_io_next) { 17 if (ev->ev_events & events) 18 event_active_nolock_(ev, ev->ev_events & events, 1); 19 } 20 }
遍历evmap_io的成员events,在每一次遍历中实际调用ev_active_nolock_
1 void 2 event_active_nolock_(struct event *ev, int res, short ncalls) 3 { 4 struct event_base *base; 5 6 event_debug(("event_active: %p (fd "EV_SOCK_FMT"), res %d, callback %p", 7 ev, EV_SOCK_ARG(ev->ev_fd), (int)res, ev->ev_callback)); 8 9 base = ev->ev_base; 10 EVENT_BASE_ASSERT_LOCKED(base); 11 12 if (ev->ev_flags & EVLIST_FINALIZING) { 13 /* XXXX debug */ 14 return; 15 } 16 17 switch ((ev->ev_flags & (EVLIST_ACTIVE|EVLIST_ACTIVE_LATER))) { 18 default: 19 case EVLIST_ACTIVE|EVLIST_ACTIVE_LATER: 20 EVUTIL_ASSERT(0); 21 break; 22 case EVLIST_ACTIVE: 23 /* We get different kinds of events, add them together */ 24 ev->ev_res |= res; 25 return; 26 case EVLIST_ACTIVE_LATER: 27 ev->ev_res |= res; 28 break; 29 case 0: 30 ev->ev_res = res; 31 break; 32 } 33 34 if (ev->ev_pri < base->event_running_priority) 35 base->event_continue = 1; 36 37 if (ev->ev_events & EV_SIGNAL) { 38 #ifndef EVENT__DISABLE_THREAD_SUPPORT 39 if (base->current_event == event_to_event_callback(ev) && 40 !EVBASE_IN_THREAD(base)) { 41 ++base->current_event_waiters; 42 EVTHREAD_COND_WAIT(base->current_event_cond, base->th_base_lock); 43 } 44 #endif 45 ev->ev_ncalls = ncalls; 46 ev->ev_pncalls = NULL; 47 } 48 49 event_callback_activate_nolock_(base, event_to_event_callback(ev)); 50 }
该函数在最后又调用函数event_callback_activate_nolock
1 int 2 event_callback_activate_nolock_(struct event_base *base, 3 struct event_callback *evcb) 4 { 5 int r = 1; 6 7 if (evcb->evcb_flags & EVLIST_FINALIZING) 8 return 0; 9 10 switch (evcb->evcb_flags & (EVLIST_ACTIVE|EVLIST_ACTIVE_LATER)) { 11 default: 12 EVUTIL_ASSERT(0); 13 case EVLIST_ACTIVE_LATER: 14 event_queue_remove_active_later(base, evcb); 15 r = 0; 16 break; 17 case EVLIST_ACTIVE: 18 return 0; 19 case 0: 20 break; 21 } 22 23 event_queue_insert_active(base, evcb); 24 25 if (EVBASE_NEED_NOTIFY(base)) 26 evthread_notify_base(base); 27 28 return r; 29 }
该函数最后又调用event_queue_insert_active
1 static void 2 event_queue_insert_active(struct event_base *base, struct event_callback *evcb) 3 { 4 EVENT_BASE_ASSERT_LOCKED(base); 5 6 if (evcb->evcb_flags & EVLIST_ACTIVE) { 7 /* Double insertion is possible for active events */ 8 return; 9 } 10 11 INCR_EVENT_COUNT(base, evcb->evcb_flags); 12 13 evcb->evcb_flags |= EVLIST_ACTIVE; 14 15 base->event_count_active++; 16 MAX_EVENT_COUNT(base->event_count_active_max, base->event_count_active); 17 EVUTIL_ASSERT(evcb->evcb_pri < base->nactivequeues); 18 TAILQ_INSERT_TAIL(&base->activequeues[evcb->evcb_pri], 19 evcb, evcb_active_next); 20 }
1、L18将该事件插入到event_base.activequeues队列中。
函数调用关系图:
待续。。。