博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
libev学习之ev_run
阅读量:5767 次
发布时间:2019-06-18

本文共 8644 字,大约阅读时间需要 28 分钟。

好吧,神马都init好了,loop毕竟是个环呐,在哪跑起来呢,ok,他是ev_run的工作:

int ev_run (EV_P_ int flags){#if EV_FEATURE_API  ++loop_depth;#endif  assert (("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE));  loop_done = EVBREAK_CANCEL;  EV_INVOKE_PENDING; /* in case we recurse, ensure ordering stays nice and clean */  do    {#if EV_VERIFY >= 2      ev_verify (EV_A);#endif#ifndef _WIN32      if (expect_false (curpid)) /* penalise the forking check even more */        if (expect_false (getpid () != curpid))          {            curpid = getpid ();            postfork = 1;          }#endif#if EV_FORK_ENABLE      /* we might have forked, so queue fork handlers */      if (expect_false (postfork))        if (forkcnt)          {            queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK);            EV_INVOKE_PENDING;          }#endif#if EV_PREPARE_ENABLE      /* queue prepare watchers (and execute them) */      if (expect_false (preparecnt))        {          queue_events (EV_A_ (W *)prepares, preparecnt, EV_PREPARE);          EV_INVOKE_PENDING;        }#endif      if (expect_false (loop_done))        break;      /* we might have forked, so reify kernel state if necessary */      if (expect_false (postfork))        loop_fork (EV_A);      /* update fd-related kernel structures */      fd_reify (EV_A);      /* calculate blocking time */      {        ev_tstamp waittime  = 0.;        ev_tstamp sleeptime = 0.;        /* remember old timestamp for io_blocktime calculation */        ev_tstamp prev_mn_now = mn_now;        /* update time to cancel out callback processing overhead */        time_update (EV_A_ 1e100);        /* from now on, we want a pipe-wake-up */        pipe_write_wanted = 1;        ECB_MEMORY_FENCE; /* make sure pipe_write_wanted is visible before we check for potential skips */        if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped)))          {            waittime = MAX_BLOCKTIME;            if (timercnt)              {                ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now;                if (waittime > to) waittime = to;              }#if EV_PERIODIC_ENABLE            if (periodiccnt)              {                ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now;                if (waittime > to) waittime = to;              }#endif            /* don't let timeouts decrease the waittime below timeout_blocktime */            if (expect_false (waittime < timeout_blocktime))              waittime = timeout_blocktime;            /* at this point, we NEED to wait, so we have to ensure */            /* to pass a minimum nonzero value to the backend */            if (expect_false (waittime < backend_mintime))              waittime = backend_mintime;            /* extra check because io_blocktime is commonly 0 */            if (expect_false (io_blocktime))              {                sleeptime = io_blocktime - (mn_now - prev_mn_now);                if (sleeptime > waittime - backend_mintime)                  sleeptime = waittime - backend_mintime;                if (expect_true (sleeptime > 0.))                  {                    ev_sleep (sleeptime);                    waittime -= sleeptime;                  }              }          }#if EV_FEATURE_API        ++loop_count;#endif        assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */        backend_poll (EV_A_ waittime);        assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */        pipe_write_wanted = 0; /* just an optimisation, no fence needed */        ECB_MEMORY_FENCE_ACQUIRE;        if (pipe_write_skipped)          {            assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w)));            ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM);          }        /* update ev_rt_now, do magic */        time_update (EV_A_ waittime + sleeptime);      }      /* queue pending timers and reschedule them */      timers_reify (EV_A); /* relative timers called last */#if EV_PERIODIC_ENABLE      periodics_reify (EV_A); /* absolute timers called first */#endif#if EV_IDLE_ENABLE      /* queue idle watchers unless other events are pending */      idle_reify (EV_A);#endif#if EV_CHECK_ENABLE      /* queue check watchers, to be executed first */      if (expect_false (checkcnt))        queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK);#endif      EV_INVOKE_PENDING;    }  while (expect_true (    activecnt    && !loop_done    && !(flags & (EVRUN_ONCE | EVRUN_NOWAIT))  ));  if (loop_done == EVBREAK_ONE)    loop_done = EVBREAK_CANCEL;#if EV_FEATURE_API  --loop_depth;#endif  return activecnt;}

看到了那么多ifdef有木有想shi的赶脚,尼玛。对于win32下,我们来精简下,哈哈:

1 int  2 ev_run (EV_P_ int flags)  3 {  4   assert (("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE));  5   6   loop_done = EVBREAK_CANCEL;  7  //激活已经pending的事件  8   EV_INVOKE_PENDING; /* in case we recurse, ensure ordering stays nice and clean */  9  10   do 11     { 12       if (expect_false (curpid)) /* penalise the forking check even more */ 13         if (expect_false (getpid () != curpid)) 14           { 15             curpid = getpid (); 16             postfork = 1; 17           } 18  19       if (expect_false (loop_done)) 20         break; 21  22       /* update fd-related kernel structures */ 23       fd_reify (EV_A);//把更改的事件进行更新 24  25       /* calculate blocking time */ 26       { 27         ev_tstamp waittime  = 0.; 28         ev_tstamp sleeptime = 0.; 29  30         /* remember old timestamp for io_blocktime calculation */ 31         ev_tstamp prev_mn_now = mn_now; 32  33         /* update time to cancel out callback processing overhead */ 34         time_update (EV_A_ 1e100); 35  36         /* from now on, we want a pipe-wake-up */ 37         pipe_write_wanted = 1; 38  39         ECB_MEMORY_FENCE; /* make sure pipe_write_wanted is visible before we check for potential skips */ 40  41         if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped))) 42           { 43             waittime = MAX_BLOCKTIME; 44  45             if (timercnt) 46               { 47                 ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now; 48                 if (waittime > to) waittime = to; 49               } 50  51             /* don't let timeouts decrease the waittime below timeout_blocktime */ 52             if (expect_false (waittime < timeout_blocktime)) 53               waittime = timeout_blocktime; 54  55             /* at this point, we NEED to wait, so we have to ensure */ 56             /* to pass a minimum nonzero value to the backend */ 57             if (expect_false (waittime < backend_mintime)) 58               waittime = backend_mintime; 59  60             /* extra check because io_blocktime is commonly 0 */ 61             if (expect_false (io_blocktime)) 62               { 63                 sleeptime = io_blocktime - (mn_now - prev_mn_now); 64  65                 if (sleeptime > waittime - backend_mintime) 66                   sleeptime = waittime - backend_mintime; 67  68                 if (expect_true (sleeptime > 0.)) 69                   { 70                     ev_sleep (sleeptime); //以上这么大一堆,都是在计算必要的sleep事件,其实就是阻塞嘛 71                     waittime -= sleeptime; 72                   } 73               } 74           } 75  76         assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */ 77         backend_poll (EV_A_ waittime);//这里开始调用上层封装的epool,select进行轮询,收集pending事件 78         assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */ 79  80         pipe_write_wanted = 0; /* just an optimisation, no fence needed */ 81  82         ECB_MEMORY_FENCE_ACQUIRE; 83         if (pipe_write_skipped) 84           { 85             assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w))); 86             ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM); 87           } 88  89  90         /* update ev_rt_now, do magic */ 91         time_update (EV_A_ waittime + sleeptime); 92       } 93  94       /* queue pending timers and reschedule them */ 95       timers_reify (EV_A); /* relative timers called last *///对pending的timer事件进行收集 96  97       EV_INVOKE_PENDING; //遍历所有pending事件 98     } 99   while (expect_true (100     activecnt101     && !loop_done102     && !(flags & (EVRUN_ONCE | EVRUN_NOWAIT))103   ));104 105   if (loop_done == EVBREAK_ONE)106     loop_done = EVBREAK_CANCEL;107 108   return activecnt;109 }

 所有总结下,ev_run是libev的核心,

他主要做了五件事情:

1.更新更改的FD事件

2.进行必要的sleep

3.backend_poll收集pending的IO事件

4.收集pending的timer事件

5.调用所有pending的事件

ok,就是这样了!但是还有很多细节啊,尼玛代码之虐心,非比寻常啊!

 

转载地址:http://hyfux.baihongyu.com/

你可能感兴趣的文章
iOS开发中耳机的那点事(监听耳机拔插、耳机线控)(转)
查看>>
flashbuilder经典案例
查看>>
oracle递归函数
查看>>
MongoDB学习笔记(二) 通过samus驱动实现基本数据操作
查看>>
OkHttp IllegalArgumentException 异常解决方法
查看>>
Device eth0 does not seem to be present, delaying initialization. [FAILED]
查看>>
Linux 内核
查看>>
获取广西财经学院教务系统验证码Demo(hls编辑)
查看>>
代码处理技巧
查看>>
跟我从零基础学习Unity3D开发--初识U3D
查看>>
ubuntu常用配置整理
查看>>
【C语言探索之旅】 第二部分第三课:数组
查看>>
axios升级指南
查看>>
maven 学习笔记
查看>>
MongoDB常用脚本配置方法
查看>>
linux下http配置大全
查看>>
IOS学习之数据库(4)--SQLite的应用
查看>>
keepalived-2-配置文件详解
查看>>
Java NIO 概述
查看>>
015,spring boot集成Jpa
查看>>