ev_realloc()
函数原型:
//static
inline_speed void *
ev_realloc (void *ptr, long size)
{
ptr = alloc (ptr, size);//alloc 是函数指针,其将调用 ev_realloc_emul() 函数来申请内存
if (!ptr && size)//申请失败
{
#if EV_AVOID_STDIO
ev_printerr ("(libev) memory allocation failed, aborting.\n");
#else
fprintf (stderr, "(libev) cannot allocate %ld bytes, aborting.", size);
#endif
abort ();//终止程序
}
return ptr;
}
该函数的底层使用realloc() 函数,通过传递的指针和size的参数来使用。如果想要扩充内存和缩小内存,必须要绕过 ev_malloc() 和 ev_free() 因为它们只支持一个参数。
示例:
struct ev_loop* p;
printf("p:%d\n",p);
p = ev_loop_new(sizeof (ev_loop));
printf("p:%d\n",p);
ev_now()
函数声明:
EV_API_DECL ev_tstamp ev_now (EV_P) EV_THROW; /* time w.r.t. timers and the eventloop, updated after each poll */
/*时间计时器和事件循环,在每次轮询后更新*/
函数定义:
#if EV_MULTIPLICITY
ev_tstamp //double
ev_now (EV_P) EV_THROW // 参数是ev_loop*
{
return ev_rt_now;
//#define ev_rt_now ((loop)->ev_rt_now)
}
#endif
这个函数返回是POSIX时期距离现在的一个秒数
示例:
ev_tstamp time = ev_now(p);
printf("time:%lf\n",time);
ev_loop_destory()
函数声明:
/* destroy event loops, also works for the default loop */
/* 销毁事件循环,也适用与默认循环*/
EV_API_DECL void ev_loop_destroy (EV_P);
函数原型:
/* free up a loop structure */
/* 释放循环结构 */
ecb_cold
void
ev_loop_destroy (EV_P) // 参数是 ev_loop*
{
int i;
#if EV_MULTIPLICITY
/* mimic free (0) */
/* 模拟释放 */
if (!EV_A)
return; // EV_A为空
#endif
#if EV_CLEANUP_ENABLE
/* queue cleanup watchers (and execute them) */
/* 队列清理监视器,并执行,因为这个循环可能已经绑定了多个监视器 */
if (expect_false (cleanupcnt))
//#define cleanupcnt ((loop)->cleanupcnt)
//#define expect_false(cond) ecb_expect_false (cond)
//#define ecb_expect_false(expr) ecb_expect (!!(expr), 0)
//#define ecb_expect(expr,value) (expr)
//所以结果就是 if( (loop)->cleanupcnt ){} 拒绝套娃
{
queue_events (EV_A_ (W *)cleanups, cleanupcnt, EV_CLEANUP);
//queue_events(struct ev_loop* loop, ev_watcher** cleanups, int loop->cleanupcnt, int EV_CLEANUP);
//loop->cleanupcnt 代表要清理的监视器的数量
EV_INVOKE_PENDING;//(loop)->invoke_cb (loop)
}
#endif
#if EV_CHILD_ENABLE
//#define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */ /* 启动观察程序后为真 */
if (ev_is_default_loop (EV_A) && ev_is_active (&childev))
{
ev_ref (EV_A); /* child watcher */
ev_signal_stop (EV_A_ &childev);
}
#endif
if (ev_is_active (&pipe_w))
{
/*ev_ref (EV_A);*/
/*ev_io_stop (EV_A_ &pipe_w);*/
// # define EV_WIN32_CLOSE_FD(fd) close (fd)
// #define evpipe ((loop)->evpipe)
if (evpipe [0] >= 0) EV_WIN32_CLOSE_FD (evpipe [0]);
if (evpipe [1] >= 0) EV_WIN32_CLOSE_FD (evpipe [1]);
}
#if EV_USE_SIGNALFD
if (ev_is_active (&sigfd_w))
close (sigfd);
#endif
#if EV_USE_INOTIFY
if (fs_fd >= 0)
close (fs_fd);
#endif
if (backend_fd >= 0)
close (backend_fd);
// 根据底层的实现,选择性销毁
#if EV_USE_IOCP
if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A);
#endif
#if EV_USE_PORT
if (backend == EVBACKEND_PORT ) port_destroy (EV_A);
#endif
#if EV_USE_KQUEUE
if (backend == EVBACKEND_KQUEUE) kqueue_destroy (EV_A);
#endif
#if EV_USE_EPOLL
if (backend == EVBACKEND_EPOLL ) epoll_destroy (EV_A);
#endif
#if EV_USE_POLL
if (backend == EVBACKEND_POLL ) poll_destroy (EV_A);
#endif
#if EV_USE_SELECT
if (backend == EVBACKEND_SELECT) select_destroy (EV_A);
#endif
for (i = NUMPRI; i--; )
{
array_free (pending, [i]);
#if EV_IDLE_ENABLE
array_free (idle, [i]);
#endif
}
ev_free (anfds); anfds = 0; anfdmax = 0;
/* have to use the microsoft-never-gets-it-right macro */
array_free (rfeed, EMPTY);
array_free (fdchange, EMPTY);
array_free (timer, EMPTY);
#if EV_PERIODIC_ENABLE
array_free (periodic, EMPTY);
#endif
#if EV_FORK_ENABLE
array_free (fork, EMPTY);
#endif
#if EV_CLEANUP_ENABLE
array_free (cleanup, EMPTY);
#endif
array_free (prepare, EMPTY);
array_free (check, EMPTY);
#if EV_ASYNC_ENABLE
array_free (async, EMPTY);
#endif
backend = 0;
#if EV_MULTIPLICITY
if (ev_is_default_loop (EV_A))
#endif
ev_default_loop_ptr = 0;
#if EV_MULTIPLICITY
else
ev_free (EV_A);
#endif
}
涉及到的一些函数 和 结构体:
W,WL,WT
typedef ev_watcher *W;
typedef ev_watcher_list *WL;
typedef ev_watcher_time *WT;
queue_events()
inline_speed void
queue_events (EV_P_ W *events, int eventcnt, int type)
{
//events 是二级指针
//events[i] 是一级指针
int i;
//eventcnt 事件数量
for (i = 0; i < eventcnt; ++i)
ev_feed_event (EV_A_ events [i], type);
}
ev_feed_event()
noinline
void
ev_feed_event (EV_P_ void *w, int revents) EV_THROW
{
// pendingmax记录的是每个等级已经记录的监视器的个数
// pendingcnt记录的是每个等级中当前有效的监视器的个数 和 ev_watcher 里面的 pending有很大的相关性
//pengdings的每一个元素是一个ANPENDING 指针
W w_ = (W)w;//ev_watcher* w_ = (ev_watcher*)event[i]
int pri = ABSPRI (w_);//根据优先级,运算pending数组的下标,同一个优先级的监视器有很多,它们放在同一个pending数组里。
if (expect_false (w_->pending))
// if( w_->pending )
pendings [pri][w_->pending - 1].events |= revents;//ce
// pengdings 是一个二维数组
// #define pendings ((loop)->pendings)
//w_->pending-1 是当前优先级数组里的具体的项
else
{
w_->pending = ++pendingcnt [pri];
// #define pendingcnt ((loop)->pendingcnt)
//申请数组空间
array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending, EMPTY2);
//存放数据
pendings [pri][w_->pending - 1].w = w_;
pendings [pri][w_->pending - 1].events = revents;
}
pendingpri = NUMPRI - 1;
// #define NUMPRI (EV_MAXPRI - EV_MINPRI + 1) 优先级的数量
// #define pendingpri ((loop)->pendingpri)
}
array_needsize()
//一个函数非得用宏定义的方式定义
#define array_needsize(type,base,cur,cnt,init) \
if (expect_false ((cnt) > (cur))) \
{ \
ecb_unused int ocur_ = (cur);/* #define ecb_unused ecb_attribute ((__unused__)) */ \
(base) = (type *)array_realloc \
(sizeof (type), (base), &(cur), (cnt)); \
init ((base) + (ocur_), (cur) - ocur_); \
}
array_realloc()
noinline ecb_cold
static void *
array_realloc (int elem, void *base, int *cur, int cnt)
{
*cur = array_nextsize (elem, *cur, cnt);
return ev_realloc (base, elem * *cur);
}
array_nextsize()
inline_size int
array_nextsize (int elem, int cur, int cnt)
{
int ncur = cur + 1;
do
ncur <<= 1; // ncur = ncur << 1 左移1位,扩大两倍
while (cnt > ncur);
/* if size is large, round to MALLOC_ROUND - 4 * longs to accommodate malloc overhead */
/* 这是一系列运算,将大的ncur 再缩小一点,以得到最合适的大小 */
// #define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */
if (elem * ncur > MALLOC_ROUND - sizeof (void *) * 4)
{
ncur *= elem;
ncur = (ncur + elem + (MALLOC_ROUND - 1) + sizeof (void *) * 4) & ~(MALLOC_ROUND - 1);
ncur = ncur - sizeof (void *) * 4;
ncur /= elem;
}
return ncur;//返回一个新的合适的数组大小
}
ev_ref()
void
ev_ref (EV_P) EV_THROW
{
++activecnt;
// #define activecnt ((loop)->activecnt)
}
array_free()
#define array_free(stem, idx) \
ev_free (stem ## s idx); stem ## cnt idx = stem ## max idx = 0; stem ## s idx = 0
// #define ev_free(ptr) ev_realloc ((ptr), 0)