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队列中。

 

函数调用关系图:

待续。。。

posted @ 2017-01-12 07:55  冷冰若水  阅读(1702)  评论(0编辑  收藏  举报