zoukankan      html  css  js  c++  java
  • libev ev_io_init学习

    #define ev_io_init(ev,cb,fd,events)    /     
    do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)/

    看到没,这就是C语言的恶心指出,尼玛找个定一点都要用全局搜索字符,才找到这个宏。

    好吧,看它都做了写神马东东:

    ev_init ((ev), (cb));就是把watcher进行初始化,把回调设置进去;

    ev是神马玩意呢,就是ev_io:

    /* invoked when fd is either EV_READable or EV_WRITEable */
    /* revent EV_READ, EV_WRITE */
    typedef struct ev_io
    {
      EV_WATCHER_LIST (ev_io)//watcher链表
    
      int fd;     /* ro */
      int events; /* ro */
    } ev_io;

    ev_io_set ((ev),(fd),(events));就是把watcher的fd 和 events分别进行设置。

    ok。举个例子:

    #include <ev.h>
    #include <stdio.h> // for puts
    
    // every watcher type has its own typedef'd struct
    // with the name ev_TYPE
    ev_io stdin_watcher;
    
    // all watcher callbacks have a similar signature
    // this callback is called when data is readable on stdin
    static void stdin_cb (EV_P_ ev_io *w, int revents)//时间回调
    {
      puts ("stdin ready");
      // for one-shot events, one must manually stop the watcher
      // with its corresponding stop function.
      ev_io_stop (EV_A_ w);
    
      // this causes all nested ev_run's to stop iterating
      ev_break (EV_A_ EVBREAK_ALL);
    }
    
    int main (void)
    {
      // use the default event loop unless you have special needs
      struct ev_loop *loop = EV_DEFAULT;
    
      // initialise an io watcher, then start it
      // this one will watch for stdin to become readable
      ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
      ev_io_start (loop, &stdin_watcher);
    
      // now wait for events to arrive
      ev_run (loop, 0);
    
      // break was called, so exit
      return 0;
    }
    

      ok,这样,通过ev_io_init就把我们关注的事件和回调放进ev_io;

    但这时候还与loop木有关系哇,是的,看后面一句调用:ev_io_start

    不过貌似libev版本升级啦,这个函数签名都改版了:

    void noinline ev_io_start (EV_P_ ev_io *w) EV_THROW
    {
      int fd = w->fd;
    
      //如果已经是active的就返回
    if (expect_false (ev_is_active (w))) return; assert (("libev: ev_io_start called with negative fd", fd >= 0)); assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE)))); EV_FREQUENT_CHECK; ev_start (EV_A_ (W)w, 1); array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero); wlist_add (&anfds[fd].head, (WL)w); /* common bug, apparently */ assert (("libev: ev_io_start called with corrupted watcher", ((WL)w)->next != (WL)w)); fd_change (EV_A_ fd, w->events & EV__IOFDSET | EV_ANFD_REIFY); w->events &= ~EV__IOFDSET; EV_FREQUENT_CHECK; }
    其中有个函数:
    inline_speed void ev_start (EV_P_ W w, int active)
    {
      pri_adjust (EV_A_ w);//设置优先级,其中会check io的pri,然后把check后的pri设置进去,如果我们默认pri=0,其实调用前后木有神马变化
      w->active = active;//active=1,表示设置为active
      ev_ref (EV_A);//loop里的activecnt进行++,就是对io进行统计吧
    }

    wlist_add (&anfds[fd].head, (WL)w);//对一个fd 添加需要的事件列表,不过还木有看见过对一个fd添加很多事件的情况

    /*****************************************************************************/
    /* singly-linked list management, used when the expected list length is short */ 

    inline_size void wlist_add (WL *head, WL elem)//很明显是头插法,把当前watecher插到list头部,然后替换

    {
    elem->next = *head;
    *head = elem;
    }

    ok,最后一个函数:

    /* something about the given fd changed */
    inline_size void fd_change (EV_P_ int fd, int flags)
    {
      unsigned char reify = anfds [fd].reify;
      anfds [fd].reify |= flags;
    
      if (expect_true (!reify))
        {
          ++fdchangecnt;
          array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2);
          fdchanges [fdchangecnt - 1] = fd;
        }
    }

    暂时没搞懂上面的函数是搞神马的,之后再看,或者明白的网友看到了,给讲下啊

  • 相关阅读:
    JS小技巧总汇
    [转贴]聪明人如何拯救你的职业困
    Button按钮多行显示的实现方法
    事件和委托
    支持~
    关于递归
    Android 资源的国际化
    Android 文件的浏览(类似于FileDialog的功能)
    Android 开发TCP、UdP客户端
    Android 为什么现在google不让结束整个程序,只让结束单个Activity(转)
  • 原文地址:https://www.cnblogs.com/xiangshancuizhu/p/3250337.html
Copyright © 2011-2022 走看看