IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C-libev学习笔记-事件库源码阅读8-API-ev_realloc(),ev_now(),ev_loop_destroy() -> 正文阅读

[C++知识库]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)
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-22 14:29:00  更:2021-09-22 14:29:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 21:35:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码