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語言的噁心指出,尼瑪找個定一點都要用全局搜索字符,才找到這個宏。app

好吧,看它都作了寫神馬東東:less

ev_init ((ev), (cb));就是把watcher進行初始化,把回調設置進去;函數

ev是神馬玩意呢,就是ev_io:oop

/* 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分別進行設置。this

ok。舉個例子:spa

#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;code

但這時候還與loop木有關係哇,是的,看後面一句調用:ev_io_startblog

不過貌似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 */ ci

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;
    }
}

暫時沒搞懂上面的函數是搞神馬的,以後再看,或者明白的網友看到了,給講下啊

相關文章
相關標籤/搜索