尼玛 C语言学不好真是桑心呐!

看了libev的代码有一种想死的感觉,但是还是要硬着头皮看下去,一定看完!

/* initialise a loop structure, must be zero-initialised */
static void loop_init ( unsigned int flags)
{
if (!loop->backend)
{
origflags = flags; #if EV_USE_REALTIME
if (!have_realtime)
{
struct timespec ts; if (!clock_gettime (CLOCK_REALTIME, &ts))
have_realtime = ;
}
#endif #if EV_USE_MONOTONIC
if (!have_monotonic)
{
struct timespec ts; if (!clock_gettime (CLOCK_MONOTONIC, &ts))
have_monotonic = ;
}
#endif /* pid check not overridable via env */
#ifndef _WIN32
if (flags & EVFLAG_FORKCHECK)
curpid = getpid ();
#endif if (!(flags & EVFLAG_NOENV)
&& !enable_secure ()
&& getenv ("LIBEV_FLAGS"))
flags = atoi (getenv ("LIBEV_FLAGS")); ev_rt_now = ev_time ();
mn_now = get_clock ();
now_floor = mn_now;
rtmn_diff = ev_rt_now - mn_now;
#if EV_FEATURE_API
invoke_cb = ev_invoke_pending;
#endif io_blocktime = .;
timeout_blocktime = .;
backend = ;
backend_fd = -;
sig_pending = ;
#if EV_ASYNC_ENABLE
async_pending = ;
#endif
pipe_write_skipped = ;
pipe_write_wanted = ;
evpipe [] = -;
evpipe [] = -;
#if EV_USE_INOTIFY
fs_fd = flags & EVFLAG_NOINOTIFY ? - : -;
#endif
#if EV_USE_SIGNALFD
sigfd = flags & EVFLAG_SIGNALFD ? - : -;
#endif if (!(flags & EVBACKEND_MASK))
flags |= ev_recommended_backends (); #if EV_USE_IOCP
if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags);
#endif
#if EV_USE_PORT
if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags);
#endif
#if EV_USE_KQUEUE
if (!backend && (flags & EVBACKEND_KQUEUE)) backend = kqueue_init (EV_A_ flags);
#endif
#if EV_USE_EPOLL
if (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init (EV_A_ flags);
#endif
#if EV_USE_POLL
if (!backend && (flags & EVBACKEND_POLL )) backend = poll_init (EV_A_ flags);
#endif
#if EV_USE_SELECT
if (!backend && (flags & EVBACKEND_SELECT)) backend = select_init (EV_A_ flags);
#endif ev_prepare_init (&pending_w, pendingcb); #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
ev_init (&pipe_w, pipecb);
ev_set_priority (&pipe_w, EV_MAXPRI);
#endif
}
}

主要就是初始化loop中的数据成员,其中最重要的是backend的初始化,比如win32选择IOCP,Select等,获取当前时间等。

void *event_init (void)
{
#if EV_MULTIPLICITY //定义多线程,就是可以有多个loop
if (ev_x_cur)
ev_x_cur = (struct event_base *)ev_loop_new (EVFLAG_AUTO);
else
ev_x_cur = (struct event_base *)ev_default_loop (EVFLAG_AUTO);
#else
assert (("libev: multiple event bases not supported when not compiled with EV_MULTIPLICITY", !ev_x_cur)); ev_x_cur = (struct event_base *)(long)ev_default_loop (EVFLAG_AUTO);
#endif return ev_x_cur;
}

其中ev_default_loop就是把一个全局的static loop赋给ev_default_loop_ptr,然后返回。这样就可以全局用define的东东调来调去,好不羞涩。

ev_loop_new就new出来一个loop并对loop进行初始化。

ok,第一步完成!

libev loop_init分析的更多相关文章

  1. libev实现分析

    libev是一个事件驱动库,底层是基于select.epoll.kqueue等I/O复用接口.所谓事件驱动库,就是用户定义一个事件以及改事件发生时调用的函数,该库会监听该事件,并在事件发生时调用相应的 ...

  2. libev ev_init分析

    /* these may evaluate ev multiple times, and the other arguments at most once */ /* either use ev_in ...

  3. Libev源码分析02:Libev中的IO监视器

    一:代码流程 在Libev中,启动一个IO监视器,等待该监视器上的事件触发,然后调用该监视器的回调函数.整个的流程是这样的: 首先调用ev_default_loop初始化struct  ev_loop ...

  4. [转]Libev源码分析 -- 整体设计

    Libev源码分析 -- 整体设计 libev是Marc Lehmann用C写的高性能事件循环库.通过libev,可以灵活地把各种事件组织管理起来,如:时钟.io.信号等.libev在业界内也是广受好 ...

  5. Libev源码分析08:Libev中的内存扩容方法

    在Libev中,如果某种结构的数组需要扩容,它使用array_needsize宏进行处理,比如: array_needsize (int, fdchanges, fdchangemax, fdchan ...

  6. Libev源码分析08:Libev中的信号监视器

    Libev中的信号监视器,用于监控信号的发生,因信号是异步的,所以Libev的处理方式是尽量的将异步信号同步化.异步信号的同步化方法主要有:signalfd.eventfd.pipe.sigwaiti ...

  7. Libev源码分析09:select突破处理描述符个数的限制

    众所周知,Linux下的多路复用函数select采用描述符集表示处理的描述符.描述符集的大小就是它所能处理的最大描述符限制.通常情况下该值为1024,等同于每个进程所能打开的描述符个数. 增大描述符集 ...

  8. 开源网络库的分析libev libevent nginx ....

    最经看关于网络编程的一些书,对于网络编程中的一些基本东西,开源库已经封装的很好了,但是库归根结底还是使用的基本API,所以就想着分析一下,尤其是在看了各个库的介绍以后,所以这段时间想在这个方向投入一点 ...

  9. Libev源码分析05:Libev中的绝对时间定时器

    Libev中的超时监视器ev_periodic,是绝对时间定时器,不同于ev_timer,它是基于日历时间的.比如如果指定一个ev_periodic在10秒之后触发(ev_now() + 10),然后 ...

随机推荐

  1. Android Studio中实现AIDL

    AIDL 先来两个传送门: http://www.cnblogs.com/yydcdut/p/3961545.html Android面试,与Service交互方式 http://www.cnblog ...

  2. Android -- DisplayMetrics

    干货 DisplayMetrics dm = new DisplayMetrics(); this.getWindowManager().getDefaultDisplay().getMetrics( ...

  3. 解决Ubuntu/debian的Apt-get 由于依赖关系安装失败的问题

    The following packages have unmet dependencies: libssl-dev: Depends: libssl0.9.8 (= 0.9.8k-7ubuntu8) ...

  4. OpenGL ES 3.0之Fragment buffer objects(FBO)详解(二)

    我们可以使用帧缓冲对象来实现离屏渲染.帧缓冲对象支持下列操作 1.只使用OpenGL ES 函数创建帧缓冲区对象. 2.使用EGL context创建多个FBO. 3.创建离屏颜色.深度.模板渲染缓冲 ...

  5. angular.element()的用法

    1.引用jQuery的前提下,和$用法基本相同:angular.element('#').html() 例如: angular.element('#test').html() angular.elem ...

  6. "___gxx_personality_v0", referenced from:

    这是因为里面有用到C++ 的一些东西.所以会出现这个问题 两种解决办法. 第一种.TARGETS -> Build Phases -> Link Binary With Libraries ...

  7. LintCode: 3 Sum

    C++ 把3个数求和,转变为2个数求和 1. 把数组排序 2. 注意过滤重复值 3. 从前到后遍历,游标i 4. 从后边数中找start + end = -arr[i]的2 sum 5. start ...

  8. 微信小程序 - 时间轴(组件)

    更新日期: 2019/3/6:首次发布 2019/3/7:增加content和date自定义(具体使用看示例) 时间轴 参数: 1. data(新闻列表数据)- 2019/3/6 2. content ...

  9. 微软BI 之SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表

    基于数据仓库上的 SSRS 报表展示,一般可以直接通过 SQL 查询,存储过程,视图或者表等多种方式将数据加载并呈现在报表中.但是如果是基于 Cube 多维数据集的数据查询,就不能再使用 SQL 的语 ...

  10. SpringBoot使用JSP渲染页面

    1.pom.xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...