zoukankan      html  css  js  c++  java
  • 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队列中。

    函数调用关系图:

    待续。。。

  • 相关阅读:
    Python 企业面试题集锦之Python基础
    Jmeter 线程之间传递参数
    Jmeter 5.1参数化csv引入文件
    Jmeter 5.1命令行执行bat文件
    Idea JAVA項目的导入JAR包和导出jar包
    charles 设置弱网测试
    Jmeter_Beanshell 返回值中提取参数值
    在Notepad++里配置python环境
    python json格式参数遍历所有key、value 及替换key对于的value
    python 使用yaml模块
  • 原文地址:https://www.cnblogs.com/lit10050528/p/6276697.html
Copyright © 2011-2022 走看看