libubox是在2011年加入OpenWrt的代码库的。它是OpenWrt中的一个核心库,封装了一系列基础实用功能。
libubox主要提供以下三部分功能:
提供多种基础通用功能接口,包含链表、平衡二叉树、二进制块处理、key-value链表、MD5等
基于AF-UNIX 线程间通讯协议栈,封装sock接口
提供一套基于事件驱动的机制及任务队列管理功能
它的目的是以动态链接库方式来提供可重用的通用功能,给其他模块提供便利和避免再造轮子。
本篇主要分析libubox的事件驱动机制和任务队列管理功能,OpenWRT系统管理框架就是依赖事件驱动型任务队列。
libubox基于AF-UNIX sock通讯机制和kqueue或epoll的IO框架封装实现了,事件驱动型任务队列。先回顾一下这两部分知识。
AF-UNIX
典型的本地IPC,类似于管道,依赖路径名标识发送方和接收方。即发送数据时,指定接收方绑定的路径名,操作系统根据该路径名可以直接找到对应的接收方,并将原始数据直接拷贝到接收方的内核缓冲区中,并上报给接收方进程进行处理。同样的接收方可以从收到的数据包中获取到发送方的路径名,并通过此路径名向其发送数据。
kqueue和kevent
Kqueue为应用程序提供了一个标准的API,用于注册他们感兴趣的各种事件和条件,并以有效的方式通知他们。它的设计是可伸缩,灵活,可靠和准确的。
kevent 由一对<ident, filter>进行标识。标识符ident可以是一个描述符 (文件、套接字、流)、进程ID或信号量, 这取决于我们要监视的内容。筛选器filter标识用于处理相应事件的内核筛选器。有一些预先定义的系统筛选器 (如 EVFILT_READ 或 EVFILT_WRITE),当有可进行读取或写入操作的数据时,可分别被触发。
uloop
libubox 的实现的事件驱动机制接口在uloop.c 文件,是基于epoll接口来实现的(可配置为Kqueue方式),uloop是一个I/O循环调度,将不同的文件描述符添加到轮询中。文件描述符fd的管理由 uloop_fd 结构来设置。仅需设置 fd 和事件发生时的回调函数,数据结构的其他部分供内部使用。超时管理 部分由 uloop_timeout 结构来管理,在定时时间到了之后调用回调函数,定时时间单位为 毫秒 ,常用接口: