C-libev学习笔记-事件库源码阅读8-API-ev_realloc(),ev_now(),ev_loop_destroy()

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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙子砰砰枪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值