libev作为优秀的高性能IO框架,非常值得学习!

虽然我是菜鸟,但也必须学习啦,从今天一点一点地学习,慢慢进步!

# include "ev.h"

struct event_base;

//定义事件类型码,注意啦,都是2的指数幂
#define EVLIST_TIMEOUT 0x01
#define EVLIST_INSERTED 0x02
#define EVLIST_SIGNAL 0x04
#define EVLIST_ACTIVE 0x08
#define EVLIST_INTERNAL 0x10
#define EVLIST_INIT 0x80

//定义回调函数
typedef void (*event_callback_fn)(int, short, void *); struct event
{
/* libev watchers we map onto */
 //注意,这里union表示某一时间会有一个东东,比如在win32里就只有ev_io
  union {
struct ev_io io;
struct ev_signal sig;
} iosig;
struct ev_timer to; /* compatibility slots */
struct event_base *ev_base;
event_callback_fn ev_callback;
void *ev_arg;
int ev_fd;
int ev_pri;
int ev_res;
int ev_flags;
short ev_events;
}; event_callback_fn event_get_callback (const struct event *ev); #define EV_READ EV_READ
#define EV_WRITE EV_WRITE
#define EV_PERSIST 0x10
#define EV_ET 0x20 /* nop */

//这里定义了一系列函数,其实封装成函数 感觉更好点
#define EVENT_SIGNAL(ev) ((int) (ev)->ev_fd)
#define EVENT_FD(ev) ((int) (ev)->ev_fd) #define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT) #define evtimer_add(ev,tv) event_add (ev, tv)
#define evtimer_set(ev,cb,data) event_set (ev, -1, 0, cb, data)
#define evtimer_del(ev) event_del (ev)
#define evtimer_pending(ev,tv) event_pending (ev, EV_TIMEOUT, tv)
#define evtimer_initialized(ev) event_initialized (ev) #define timeout_add(ev,tv) evtimer_add (ev, tv)
#define timeout_set(ev,cb,data) evtimer_set (ev, cb, data)
#define timeout_del(ev) evtimer_del (ev)
#define timeout_pending(ev,tv) evtimer_pending (ev, tv)
#define timeout_initialized(ev) evtimer_initialized (ev) #define signal_add(ev,tv) event_add (ev, tv)
#define signal_set(ev,sig,cb,data) event_set (ev, sig, EV_SIGNAL | EV_PERSIST, cb, data)
#define signal_del(ev) event_del (ev)
#define signal_pending(ev,tv) event_pending (ev, EV_SIGNAL, tv)
#define signal_initialized(ev) event_initialized (ev) const char *event_get_version (void);
const char *event_get_method (void); void *event_init (void);
void event_base_free (struct event_base *base); #define EVLOOP_ONCE EVLOOP_ONESHOT
int event_loop (int);
int event_loopexit (struct timeval *tv);
int event_dispatch (void); #define _EVENT_LOG_DEBUG 0
#define _EVENT_LOG_MSG 1
#define _EVENT_LOG_WARN 2
#define _EVENT_LOG_ERR 3
typedef void (*event_log_cb)(int severity, const char *msg);
void event_set_log_callback(event_log_cb cb); void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg);
int event_once (int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv); int event_add (struct event *ev, struct timeval *tv);
int event_del (struct event *ev);
void event_active (struct event *ev, int res, short ncalls); /* ncalls is being ignored */ int event_pending (struct event *ev, short, struct timeval *tv); int event_priority_init (int npri);
int event_priority_set (struct event *ev, int pri); struct event_base *event_base_new (void);
const char *event_base_get_method (const struct event_base *);
int event_base_set (struct event_base *base, struct event *ev);
int event_base_loop (struct event_base *base, int);
int event_base_loopexit (struct event_base *base, struct timeval *tv);
int event_base_dispatch (struct event_base *base);
int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv);
int event_base_priority_init (struct event_base *base, int fd); /* next line is different in the libevent+libev version */
/*libevent-include*/ #ifdef __cplusplus
}
#endif #endif

上面是声明,下面可以看定义啦!

#include <stddef.h>
#include <stdlib.h>
#include <assert.h>
# include "event.h" #if EV_MULTIPLICITY
# define dLOOPev struct ev_loop *loop = (struct ev_loop *)ev->ev_base
# define dLOOPbase struct ev_loop *loop = (struct ev_loop *)base
#else
# define dLOOPev
# define dLOOPbase
#endif /* never accessed, will always be cast from/to ev_loop */
struct event_base
{
int dummy;
}; static struct event_base *ev_x_cur;
//取得剩下的秒数
static ev_tstamp ev_tv_get (struct timeval *tv)
{
if (tv)
{
ev_tstamp after = tv->tv_sec + tv->tv_usec * 1e-;
return after ? after : 1e-;
}
else
return -.;
} #define EVENT_STRINGIFY(s) # s
#define EVENT_VERSION(a,b) EVENT_STRINGIFY (a) "." EVENT_STRINGIFY (b) const char *
event_get_version (void)
{
/* returns ABI, not API or library, version */
return EVENT_VERSION (EV_VERSION_MAJOR, EV_VERSION_MINOR);
} const char *
event_get_method (void)
{
return "libev";
} void *event_init (void)
{
#if EV_MULTIPLICITY
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;
} const char *
event_base_get_method (const struct event_base *base)
{
return "libev";
} struct event_base *
event_base_new (void)
{
#if EV_MULTIPLICITY
return (struct event_base *)ev_loop_new (EVFLAG_AUTO);
#else
assert (("libev: multiple event bases not supported when not compiled with EV_MULTIPLICITY"));
return NULL;
#endif
} void event_base_free (struct event_base *base)
{
dLOOPbase; #if EV_MULTIPLICITY
if (!ev_is_default_loop (loop))
ev_loop_destroy (loop);
#endif
} int event_dispatch (void)
{
return event_base_dispatch (ev_x_cur);
} #ifdef EV_STANDALONE
void event_set_log_callback (event_log_cb cb)
{
/* nop */
}
#endif int event_loop (int flags)
{
return event_base_loop (ev_x_cur, flags);
} int event_loopexit (struct timeval *tv)
{
return event_base_loopexit (ev_x_cur, tv);
} event_callback_fn event_get_callback
(const struct event *ev)
{
return ev->ev_callback;
} static void
ev_x_cb (struct event *ev, int revents)
{
revents &= EV_READ | EV_WRITE | EV_TIMER | EV_SIGNAL; ev->ev_res = revents;
ev->ev_callback (ev->ev_fd, (short)revents, ev->ev_arg);
} static void
ev_x_cb_sig (EV_P_ struct ev_signal *w, int revents)
{
struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.sig)); if (revents & EV_ERROR)
event_del (ev); ev_x_cb (ev, revents);
} static void
ev_x_cb_io (EV_P_ struct ev_io *w, int revents)
{
struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.io)); if ((revents & EV_ERROR) || !(ev->ev_events & EV_PERSIST))
event_del (ev); ev_x_cb (ev, revents);
} static void
ev_x_cb_to (EV_P_ struct ev_timer *w, int revents)
{
struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, to)); event_del (ev); ev_x_cb (ev, revents);
} void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg)
{
if (events & EV_SIGNAL)
ev_init (&ev->iosig.sig, ev_x_cb_sig);
else
ev_init (&ev->iosig.io, ev_x_cb_io); ev_init (&ev->to, ev_x_cb_to); ev->ev_base = ev_x_cur; /* not threadsafe, but it's how libevent works */
ev->ev_fd = fd;
ev->ev_events = events;
ev->ev_pri = ;
ev->ev_callback = cb;
ev->ev_arg = arg;
ev->ev_res = ;
ev->ev_flags = EVLIST_INIT;
} int event_once (int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
{
return event_base_once (ev_x_cur, fd, events, cb, arg, tv);
} int event_add (struct event *ev, struct timeval *tv)
{
dLOOPev; if (ev->ev_events & EV_SIGNAL)
{
if (!ev_is_active (&ev->iosig.sig))
{
ev_signal_set (&ev->iosig.sig, ev->ev_fd);
ev_signal_start (EV_A_ &ev->iosig.sig); ev->ev_flags |= EVLIST_SIGNAL;
}
}
else if (ev->ev_events & (EV_READ | EV_WRITE))
{
if (!ev_is_active (&ev->iosig.io))
{
ev_io_set (&ev->iosig.io, ev->ev_fd, ev->ev_events & (EV_READ | EV_WRITE));
ev_io_start (EV_A_ &ev->iosig.io); ev->ev_flags |= EVLIST_INSERTED;
}
} if (tv)
{
ev->to.repeat = ev_tv_get (tv);
ev_timer_again (EV_A_ &ev->to);
ev->ev_flags |= EVLIST_TIMEOUT;
}
else
{
ev_timer_stop (EV_A_ &ev->to);
ev->ev_flags &= ~EVLIST_TIMEOUT;
} ev->ev_flags |= EVLIST_ACTIVE; return ;
} int event_del (struct event *ev)
{
dLOOPev; if (ev->ev_events & EV_SIGNAL)
ev_signal_stop (EV_A_ &ev->iosig.sig);
else if (ev->ev_events & (EV_READ | EV_WRITE))
ev_io_stop (EV_A_ &ev->iosig.io); if (ev_is_active (&ev->to))
ev_timer_stop (EV_A_ &ev->to); ev->ev_flags = EVLIST_INIT; return ;
} void event_active (struct event *ev, int res, short ncalls)
{
dLOOPev; if (res & EV_TIMEOUT)
ev_feed_event (EV_A_ &ev->to, res & EV_TIMEOUT); if (res & EV_SIGNAL)
ev_feed_event (EV_A_ &ev->iosig.sig, res & EV_SIGNAL); if (res & (EV_READ | EV_WRITE))
ev_feed_event (EV_A_ &ev->iosig.io, res & (EV_READ | EV_WRITE));
} int event_pending (struct event *ev, short events, struct timeval *tv)
{
short revents = ;
dLOOPev; if (ev->ev_events & EV_SIGNAL)
{
/* sig */
if (ev_is_active (&ev->iosig.sig) || ev_is_pending (&ev->iosig.sig))
revents |= EV_SIGNAL;
}
else if (ev->ev_events & (EV_READ | EV_WRITE))
{
/* io */
if (ev_is_active (&ev->iosig.io) || ev_is_pending (&ev->iosig.io))
revents |= ev->ev_events & (EV_READ | EV_WRITE);
} if (ev->ev_events & EV_TIMEOUT || ev_is_active (&ev->to) || ev_is_pending (&ev->to))
{
revents |= EV_TIMEOUT; if (tv)
{
ev_tstamp at = ev_now (EV_A); tv->tv_sec = (long)at;
tv->tv_usec = (long)((at - (ev_tstamp)tv->tv_sec) * 1e6);
}
} return events & revents;
} int event_priority_init (int npri)
{
return event_base_priority_init (ev_x_cur, npri);
} int event_priority_set (struct event *ev, int pri)
{
ev->ev_pri = pri; return ;
} int event_base_set (struct event_base *base, struct event *ev)
{
ev->ev_base = base; return ;
} int event_base_loop (struct event_base *base, int flags)
{
dLOOPbase; return !ev_run (EV_A_ flags);
} int event_base_dispatch (struct event_base *base)
{
return event_base_loop (base, );
} static void
ev_x_loopexit_cb (int revents, void *base)
{
dLOOPbase; ev_break (EV_A_ EVBREAK_ONE);
} int event_base_loopexit (struct event_base *base, struct timeval *tv)
{
ev_tstamp after = ev_tv_get (tv);
dLOOPbase; ev_once (EV_A_ -, , after >= . ? after : ., ev_x_loopexit_cb, (void *)base); return ;
} struct ev_x_once
{
int fd;
void (*cb)(int, short, void *);
void *arg;
}; static void
ev_x_once_cb (int revents, void *arg)
{
struct ev_x_once *once = (struct ev_x_once *)arg; once->cb (once->fd, (short)revents, once->arg);
free (once);
} int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
{
struct ev_x_once *once = (struct ev_x_once *)malloc (sizeof (struct ev_x_once));
dLOOPbase; if (!once)
return -; once->fd = fd;
once->cb = cb;
once->arg = arg; ev_once (EV_A_ fd, events & (EV_READ | EV_WRITE), ev_tv_get (tv), ev_x_once_cb, (void *)once); return ;
} int event_base_priority_init (struct event_base *base, int npri)
{
/*dLOOPbase;*/ return ;
}

libev4.15学习的更多相关文章

  1. PowerDesigner 15学习笔记:十大模型及五大分类

    个人认为PowerDesigner 最大的特点和优势就是1)提供了一整套的解决方案,面向了不同的人员提供不同的模型工具,比如有针对企业架构师的模型,有针对需求分析师的模型,有针对系统分析师和软件架构师 ...

  2. requireJS(版本是2.1.15)学习教程(一)

    一:为什么要使用requireJS? 很久之前,我们所有的JS文件写到一个js文件里面去进行加载,但是当业务越来越复杂的时候,需要分成多个JS文件进行加载,比如在页面中head内分别引入a.js,b. ...

  3. ODAC(V9.5.15) 学习笔记(三)TOraSession(3)

    3. 选项 TOraSession的Options有如下内容 名称 类型 说明 CharLength TCharLength 单个字符的长度,缺省0,表示从服务器获取对应的字符集中单个字符长度 Cha ...

  4. ODAC(V9.5.15) 学习笔记(一)总论

    一直在使用ODAC做开发,没时间仔细研究一下,目前采用的是3层结构,ODAC+TDataSetProvider+TClientDataSet做数据处理,也没有多大问题.下一步要开发B/S的程序了,打算 ...

  5. 2.15 学习总结 之 天气预报APP volley(HTTP库)之StringRequest

    一.说在前面   昨天 学习了序列化的相关知识   今天 1.学习 volley(HTTP库)的 StringRequest请求 2.使用序列化完成相关案例 遇到问题 请求到的参数的出现中文乱码问题 ...

  6. 3.15学习总结(Python爬取网站数据并存入数据库)

    在官网上下载了Python和PyCharm,并在网上简单的学习了爬虫的相关知识. 结对开发的第一阶段要求: 网上爬取最新疫情数据,并存入到MySql数据库中 在可视化显示数据详细信息 项目代码: im ...

  7. ODAC (V9.5.15) 学习笔记(二十一)数据复制

    用TVirtualTable在内存中缓存TOraQuery中的数据,主要应用场景是参照其他数据,需要将TOraQuery中的数据复制到TVirtualTable,由于没有类似于TClientDataS ...

  8. ODAC (V9.5.15) 学习笔记(二十)大数据量获取处理

    ODAC获取数据的效率比较高,在Web程序中希望能够更快获取第一页的数据时,可以有几种方式: 1.在数据库中进行分页处理: 2.获取所有数据,只是快速返回第一页数据. 第一种方案对应用服务器资源消耗最 ...

  9. ODAC(V9.5.15) 学习笔记(十九)主键值自动生成

    ODAC支持通过Oracle的序列来自动生成表的主键功能.这个过程允许在客户端自动完成,不需要过多代码.这个对一些要求自动增长字段做主键的场合非常有用.其实现步骤为: 1.数据库必须先建立生成主键的序 ...

随机推荐

  1. 引用外部jquery.js

    使用 Google 的 CDN <head> <script type="text/javascript" src="http://ajax.googl ...

  2. 求通俗讲解下tensorflow的embedding_lookup接口的意思

    https://www.zhihu.com/question/48107602 作者:王凯链接:https://www.zhihu.com/question/48107602/answer/15980 ...

  3. 使用SVD方法实现电影推荐系统

    http://blog.csdn.net/zhaoxinfan/article/details/8821419 这学期选了一门名叫<web智能与社会计算>的课,老师最后偷懒,最后的课程pr ...

  4. Ubuntu mysql开启远程登录的方法

    一.问题 Ubuntu  16.0.4   mysql5.7 二.解决问题 Ubuntu中MySQL的配置文件是在/etc/mysql/mysql.conf.d/mysqld.cnf,VI该文件把 b ...

  5. Is there anyway to discover which ip addresses are connected to the db?

    From mongo shell run db.currentOp() to show all active connections or db.currentOp(true) to show all ...

  6. installers PHPManager

    === Verbose logging started: // :: Build type: SHIP UNICODE 5.00.10011.00 Calling process: C:\Progra ...

  7. echart 图例设置自定义图标?

    option = { legend: { orient: 'horizontal', // 'vertical' x: 'right', // 'center' | 'left' | {number} ...

  8. (纪录片)统计的乐趣 The Joy of Stats (2010)

    简介: 导演: 丹·希尔曼主演: Hans Rosling类型: 纪录片官方网站: www.bbc.co.uk/programmes/b00wgq0l制片国家/地区: 英国语言: 英语上映日期: 20 ...

  9. windows下根据进程ID强制杀死进程

    [windows 进程ID PID]NTSD命令详解 1. ntsd -c q -p PID 2. ntsd -c q -pn ImageName 比如:ntsd -c q -pn qq.exe -c ...

  10. js 判断l对象类型

    var obj = {}; obj.isObject = function (obj) { return Object.prototype.toString.call(obj) == '[object ...