libubox-uloop

参考:libubox组件(3)——uloop

uloop是提供事件驱动机制接口,类似libevent事件框架,基于epoll接口来实现的。

uloop三大功能:事件管理(uloop_fd)、超时管理(uloop_timeout)和进程管理(uloop_process),定义在uloop.h中。

1. 整体框架

   1:  /**

   2:   * 初始化事件循环

   3:   *主要工作是poll_fd = epoll_create(32);/* 创建一个epoll的文件描述符监控句柄。最多监控32个文件描述符 

   4:   **/

   5:  int uloop_init(void)

   6:  {

   7:      if (poll_fd >= 0)

   8:          return 0;

   9:   

  10:      poll_fd = epoll_create(32);/* 创建一个epoll的句柄。最多监控32个文件描述符 */

  11:      if (poll_fd < 0)

  12:          return -1;

  13:   

  14:      fcntl(poll_fd, F_SETFD, fcntl(poll_fd, F_GETFD) | FD_CLOEXEC); /* fd_cloexecs */

  15:      return 0;

  16:  }

  17:   

  18:   

  19:  /**

  20:   * 事件循环主处理入口

  21:   *1.当某一个进程第一次调用uloop_run时,注册sigchld和sigint信号

  22:   *2.循环获取当前时间,把超时的timeout处理掉,有一条timeout链表在维护

  23:   *3.循环检测是否收到一个sigchld信号,如果收到,删除对应的子进程,有一条process子进程链表在维护

  24:   *4.循环调用epoll_wait 监相应的触发事件文件描述符fd 

  25:   **/

  26:  void uloop_run(void)

  27:  {

  28:      static int recursive_calls = 0; /* static value */

  29:      struct timeval tv;

  30:   

  31:      /*

  32:       * Handlers are only updated for the first call to uloop_run() (and restored

  33:       * when this call is done).

  34:       */

  35:      if (!recursive_calls++) /* 第一次运行uloop_run时调用, 注册信号处理函数 */

  36:          uloop_setup_signals(true);

  37:   

  38:      uloop_cancelled = false;

  39:      while(!uloop_cancelled)

  40:      {

  41:          uloop_gettime(&tv); /* 获取当前时间 */

  42:          uloop_process_timeouts(&tv); /* 把超时的timeout清理掉 */

  43:          if (uloop_cancelled)

  44:              break;

  45:   

  46:          if (do_sigchld) /*  收到一个sigchld的信号 */

  47:              uloop_handle_processes(); /* 销毁该进程的uloop_process */

  48:          uloop_gettime(&tv);

  49:          uloop_run_events(uloop_get_next_timeout(&tv));/* 处理相应的触发事件fd */

  50:      }

  51:   

  52:      if (!--recursive_calls)

  53:          uloop_setup_signals(false);

  54:  }

  55:   

  56:   

  57:  /**

  58:   * 销毁事件循环

  59:   * 关闭epoll描述符

  60:   * 销毁子进程链表

  61:   * 销毁timeout链表

  62:  **/

  63:  void uloop_done(void)

  64:  {

  65:      if (poll_fd < 0)

  66:          return;

  67:   

  68:      close(poll_fd);

  69:      poll_fd = -1;

  70:   

  71:      uloop_clear_timeouts();

  72:      uloop_clear_processes();

  73:  }
// 设置uloop内部结束循环标志
static inline void uloop_end(void)
{
    uloop_cancelled = true;
}int uloop_init(void);void uloop_run(void);void uloop_done(void);

2. uloop_fd

uloop是一个I/O循环调度,将不同文件描述符添加到轮询中。

文件描述符fd的管理由uloop_fd结构来设置。仅需设置fd和事件发生时的回调函数,数据结构的其他部分供内部使用。

#define ULOOP_READ      (1 << 0)
#define ULOOP_WRITE     (1 << 1)
#define ULOOP_EDGE_TRIGGER  (1 << 2)
#define ULOOP_BLOCKING      (1 << 3)

#define ULOOP_EVENT_MASK    (ULOOP_READ | ULOOP_WRITE)

/* internal flags */
#define ULOOP_EVENT_BUFFERED    (1 << 4)
#ifdef USE_KQUEUE
#define ULOOP_EDGE_DEFER    (1 << 5)
#endif

#define ULOOP_ERROR_CB      (1 << 6)

struct uloop_fd
{
    uloop_fd_handler cb;
    int fd;
    bool eof;
    bool error;
    bool registered;
    uint8_t flags;
};

int uloop_fd_add(struct uloop_fd *sock, unsigned int flags);
int uloop_fd_delete(struct uloop_fd *sock);
typedef void (*uloop_fd_handler)(struct uloop_fd *u, unsigned int events);

3. uloop_timeout

超时管理部分由uloop_timeout结构来管理,在定时时间到了之后调用回调函数,定时时间单位为毫秒。

struct uloop_timeout
{
    struct list_head list;
    bool pending;

    uloop_timeout_handler cb;
    struct timeval time;
};

int uloop_timeout_add(struct uloop_timeout *timeout);
int uloop_timeout_set(struct uloop_timeout *timeout, int msecs);
int uloop_timeout_cancel(struct uloop_timeout *timeout);
int uloop_timeout_remaining(struct uloop_timeout *timeout);

typedef void (*uloop_timeout_handler)(struct uloop_timeout *t)

4. uloop_process

当前进程的子进程管理。建立一个链表,管理所有进程id。

struct uloop_process
{
    struct list_head list;
    bool pending;

    uloop_process_handler cb;
    pid_t pid;
};

int uloop_process_add(struct uloop_process *p);
int uloop_process_delete(struct uloop_process *p);

typedef void (*uloop_process_handler)(struct uloop_process *c, int ret)
时间: 2024-10-26 16:27:12

libubox-uloop的相关文章

libubox组件(3)&mdash;&mdash;uloop

一:uloop概述 uloop有三个功能: 文件描述符触发事件的监控,  timeout定时器处理, 当前进程的子进程的维护 二: uloop的整体框架 1: /** 2: * 初始化事件循环 3: *主要工作是poll_fd = epoll_create(32);/* 创建一个epoll的文件描述符监控句柄.最多监控32个文件描述符 4: **/ 5: int uloop_init(void) 6: { 7: if (poll_fd >= 0) 8: return 0; 9:   10: po

libubox

lbubox是openwrt的一个核心库,封装了一系列基础实用功能,主要提供事件循环,二进制格式处理,linux链表实现和一些JSON辅助处理. 它的目的是以动态链接库方式来提供可重用的通用功能,给其他模块提供便利和避免再造轮子. libubox主要提供三部分功能: 1)提供多种基础通用功能接口,包含链表,平衡二叉树,二进制处理,key-value链表,MD5等. 2)sock通信. 3)一套基于事件驱动的机制及任务队列管理功能. 参考文档: libubox组件(1)--usock libubo

libubox组件(1)——usock

一:相关API介绍 1.相关源码文件:usocket.h usocket.c 2.类型标志 1: #define USOCK_TCP 0 2: #define USOCK_UDP 1 3: #define USOCK_SERVER 0x0100 4: #define USOCK_NOCLOEXEC 0x0200 5: #define USOCK_NONBLOCK 0x0400 6: #define USOCK_NUMERIC 0x0800 7: #define USOCK_IPV6ONLY 0x

openwrt libubox 开发简介

简介 libubox是openwrt新版本中的一个基础库,在openwrt1407中有很多应用程序是基于libubox开发的.(如:uhttpd,odhcpd,libubus等). libubox主要提供一下两种功能: 1.提供一套基于事件驱动的机制. 2.提供多种开发支持接口.(如:链表.kv链表.平衡查找二叉树.md5.json) 使用libubox开发的好处有如下几点: 1.可以使程序基于事件驱动,从而可实现在单线程中处理多个任务. 2.基于libubox提供的开发API可以加快开发进度的

libubox组件(2)&mdash;&mdash;blob/blobmsg

一:blob相关接口 1.数据结构 1: struct blob_attr { 2: uint32_t id_len; /** 高1位为extend标志,高7位存储id, 3: * 低24位存储data的内存大小+结构大小(blob_attr) */ 4: char data[]; 5: } __packed; 6: 实际使用中每个blob_attr的长度包含:结构长度(4)+数据长度+对齐特性= id_len+pad_len 7: struct blob_attr_info { 8: unsi

libubox-ustream

参考:libubox [4] - uloop runqueue ustream libubox提供了流缓冲管理,定义在文件ustream.h,ustream.c和ustream-fd.c. 1. 数据结构 struct ustream_buf { struct ustream_buf *next; char *data; /** 指向上次操作buff开始地址 */ char *tail; /** 指向未使用buff开始地址 */ char *end; /** 指向buf结束地址 */ char

libubox-runqueue_转

转自:libubox [4] - uloop runqueue ustream 任务队列是通过uloop定时器实现,把定时器超时时间设置为1,通过uloop事件循环来处理定时器就会处理任务队列中的task.进程任务在任务队列基本上实现,加入子进程退出监控. procd采用此机制. 1. 数据结构 struct runqueue { struct safe_list tasks_active; /** 活动任务队列 */ struct safe_list tasks_inactive; /** 不

tr069开源协议EasyCwmp移植

1.平台MT7628 2.交叉编译器及版本信息mipsel-linux + buildroot-gcc463_32bits.tar.bz2 3.创建工作目录[email protected]:~$ mkdir -p tr069/usr [email protected]:~/tr069/usr$ pwd/home/lancer/tr069/usr 4.移植json-c ----------------------------------------------------------------

Openwrt 初探

最近想研究一下Openwrt,于是开始搭建openwrt环境,虽然现在没有现成的板子,但是 可以先编译起来. 看了别人的帖子,都推荐使用svn从官网下载源码, svn co svn://svn.openwrt.org/openwrt/trunk/ 但是实际测试发现它的速度太慢了,为了得到官方的源码,从github上找到了它: https://github.com/openwrt-mirror/openwrt 将它下载下来之后,要安装一些必要的包来编译它,我使用的是ubuntu12.04. sud