libubox
摘自:https://my.oschina.net/u/1777349/blog/599651
摘自:https://blog.csdn.net/chengxing6375/article/details/100838511
libubox是openwrt新版本中的一个基础库,在openwrt.14.07中有很多应用程序是基于libubox开发的。(如:uhttpd,libubus等)。
libubox主要提供一下两种功能:
1、提供一套基于事件驱动的机制。
2、提供多种开发支持接口。(如:链表、kv链表、平衡查找二叉树、md5、json)
使用libubox开发的好处有如下几点:
1、可以使程序基于事件驱动,从而可实现在单线程中处理多个任务。
2、基于libubox提供的开发API可以加快开发进度的同事提高程序的稳定性。
3、能更好的将程序融入openwrt的架构中,因为新的openwrt的很多应用和库都基于libubox开发的。
综上所述,libubox是您玩新版openwrt必修的一个东东,相信它也值得大家去研究学习。
事件框架
uloop.c/h:
主框架
/** * 初始化事件循环 */ int uloop_init(void) /** * 事件循环主处理入口 */ void uloop_run(void) /** * 销毁事件循环 */ void uloop_done(void)
描述符结构体 struct uloop_fd { uloop_fd_handler cb; /** 描述符事件处理函数 */ int fd; /** 文件描述符,调用者初始化 */ bool eof; bool error; bool registered; /** 是否已注册到uloop中 */ uint8_t flags; }; 定时器结构体 struct uloop_timeout { struct list_head list; bool pending; uloop_timeout_handler cb; /** 定时事件处理函数 */ struct timeval time; /** 时间结构体 */ }; 进程结构体 struct uloop_process { struct list_head list; bool pending; uloop_process_handler cb; /** 进程事件处理函数 */ pid_t pid; /** 进程号*/ };
描述符事件处理函数 typedef void (*uloop_fd_handler)(struct uloop_fd *u, unsigned int events) 定时器事件处理函数 typedef void (*uloop_timeout_handler)(struct uloop_timeout *t) 进程事件处理函数 typedef void (*uloop_process_handler)(struct uloop_process *c, int ret) 事件标志 #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)
定时器事件 /** * 注册一个新定时器 */ 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)
描述符事件 /** * 注册一个新描述符到事件处理循环 */ int uloop_fd_add(struct uloop_fd *sock, unsigned int flags) /** * 从事件处理循环中销毁指定描述符 */ int uloop_fd_delete(struct uloop_fd *sock)
进程事件 /** * 注册新进程到事件处理循环 */ int uloop_process_add(struct uloop_process *p) /** * 从事件处理循环中销毁指定进程 */ int uloop_process_delete(struct uloop_process *p)
//任务队列结构体 struct runqueue { struct safe_list tasks_active; /** 活动任务队列 */ struct safe_list tasks_inactive; /** 不活动任务队列 */ struct uloop_timeout timeout; int running_tasks; /** 当前活动任务数目 */ int max_running_tasks; /** 允许最大活动任务数目 */ bool stopped; /** 是否停止任务队列 */ bool empty; /** 任务队列(包括活动和不活动)是否为空 */ /* called when the runqueue is emptied */ void (*empty_cb)(struct runqueue *q); }; //任务处理函数 struct runqueue_task_type { const char *name; /* * called when a task is requested to run * * The task is removed from the list before this callback is run. It * can re-arm itself using runqueue_task_add. */ void (*run)(struct runqueue *q, struct runqueue_task *t); /* * called to request cancelling a task * * int type is used as an optional hint for the method to be used when * cancelling the task, e.g. a signal number for processes. Calls * runqueue_task_complete when done. */ void (*cancel)(struct runqueue *q, struct runqueue_task *t, int type); /* * called to kill a task. must not make any calls to runqueue_task_complete, * it has already been removed from the list. */ void (*kill)(struct runqueue *q, struct runqueue_task *t); }; //任务结构体 struct runqueue_task { struct safe_list list; const struct runqueue_task_type *type; struct runqueue *q; void (*complete)(struct runqueue *q, struct runqueue_task *t); struct uloop_timeout timeout; int run_timeout; /** >0表示规定此任务执行只有run_timeout毫秒 */ int cancel_timeout; /** >0表示规则任务延取消操作执行只有run_timeout毫秒*/ int cancel_type; bool queued; /** 此任务是否已加入任务队列中 */ bool running; /** 此任务是否活动,即已在活动队列中 */ bool cancelled; /** 此任务是否已被取消 */ }; //进程任务结构体 struct runqueue_process { struct runqueue_task task; struct uloop_process proc; };
任务队列操作函数 /** * 初始化任务队列 */ void runqueue_init(struct runqueue *q) /** * 取消所有任务队列 */ void runqueue_cancel(struct runqueue *q); /** * 取消活动中的任务 */ void runqueue_cancel_active(struct runqueue *q); /** * 取消不活动的任务 */ void runqueue_cancel_pending(struct runqueue *q); /** * 杀死所有任务 */ void runqueue_kill(struct runqueue *q); /** * 停止所有任务 */ void runqueue_stop(struct runqueue *q); /** * 重新开始任务 */ void runqueue_resume(struct runqueue *q);
任务操作函数 /** * 添加新任务到队列尾 * * @running true-加入活动队列;false-加入不活动队列 */ void runqueue_task_add(struct runqueue *q, struct runqueue_task *t, bool running); /** * 添加新任务到队列头 * * @running true-加入活动队列;false-加入不活动队列 */ void runqueue_task_add_first(struct runqueue *q, struct runqueue_task *t, bool running); /** * 完全任务 */ void runqueue_task_complete(struct runqueue_task *t); /** * 取消任务 */ void runqueue_task_cancel(struct runqueue_task *t, int type); /** * 杀死任务 */ void runqueue_task_kill(struct runqueue_task *t);
进程任务操作函数 void runqueue_process_add(struct runqueue *q, struct runqueue_process *p, pid_t pid); /** * to be used only from runqueue_process callbacks */ void runqueue_process_cancel_cb(struct runqueue *q, struct runqueue_task *t, int type); void runqueue_process_kill_cb(struct runqueue *q, struct runqueue_task *t);
1 |
流缓冲管理
ustream.c/h/ustream-fd.c:
//流buffer结构体 struct ustream_buf { struct ustream_buf *next; char *data; /** 指向上次操作buff开始地址 */ char *tail; /** 指向未使用buff开始地址 */ char *end; /** 指向buf结束地址 */ char head[]; /** 指向buf开始地址 */ }; //流buffer结构体的链表 struct ustream_buf_list { struct ustream_buf *head; /** 指向第1块ustream_buf */ struct ustream_buf *data_tail; /** 指向未使用的ustream_buf */ struct ustream_buf *tail; /** 指向最后的ustream_buf */ int (*alloc)(struct ustream *s, struct ustream_buf_list *l); int data_bytes; /** 已用存储空间大小 */ int min_buffers; /** 可存储最小的ustream_buf块个数 */ int max_buffers; /** 可存储最大的ustream_buf块个数 */ int buffer_len; /** 每块ustream_buf块存储空间大小 */ int buffers; /** ustream_buf块个数 */ }; //读写操作的缓冲结构及操作函数 struct ustream { struct ustream_buf_list r, w; struct uloop_timeout state_change; struct ustream *next; /* * notify_read: (optional) * called by the ustream core to notify that new data is available * for reading. * must not free the ustream from this callback */ void (*notify_read)(struct ustream *s, int bytes_new); /* * notify_write: (optional) * called by the ustream core to notify that some buffered data has * been written to the stream. * must not free the ustream from this callback */ void (*notify_write)(struct ustream *s, int bytes); /* * notify_state: (optional) * called by the ustream implementation to notify that the read * side of the stream is closed (eof is set) or there was a write * error (write_error is set). * will be called again after the write buffer has been emptied when * the read side has hit EOF. */ void (*notify_state)(struct ustream *s); /* * write: * must be defined by ustream implementation, accepts new write data. * 'more' is used to indicate that a subsequent call will provide more * data (useful for aggregating writes) * returns the number of bytes accepted, or -1 if no more writes can * be accepted (link error) */ int (*write)(struct ustream *s, const char *buf, int len, bool more); /* * free: (optional) * defined by ustream implementation, tears down the ustream and frees data */ void (*free)(struct ustream *s); /* * set_read_blocked: (optional) * defined by ustream implementation, called when the read_blocked flag * changes */ void (*set_read_blocked)(struct ustream *s); /* * poll: (optional) * defined by the upstream implementation, called to request polling for * available data. * returns true if data was fetched. */ bool (*poll)(struct ustream *s); /* * ustream user should set this if the input stream is expected * to contain string data. the core will keep all data 0-terminated. */ bool string_data; /** 此ustream是否为字符串,true-是;false-否 */ bool write_error; /** 写出错,true-是;false-否 */ bool eof, eof_write_done; enum read_blocked_reason read_blocked; }; //流描述符结构体 struct ustream_fd { struct ustream stream; struct uloop_fd fd; };
//流结构操作函数 /** * ustream_fd_init: create a file descriptor ustream (uses uloop) */ void ustream_fd_init(struct ustream_fd *s, int fd) /** * ustream_init_defaults: fill default callbacks and options */ void ustream_init_defaults(struct ustream *s) /** * ustream_free: free all buffers and data associated with a ustream */ void ustream_free(struct ustream *s) //分配len空间 char *ustream_reserve(struct ustream *s, int len, int *maxlen) //移除读buffer中地一个数据结构 void ustream_consume(struct ustream *s, int len)
双向链表
list.h:
struct list_head { struct list_head *next; struct list_head *prev; }; #define LIST_HEAD_INIT(name) { &(name), &(name) } #define (name) struct list_head name = LIST_HEAD_INIT(name) static inline void INIT_LIST_HEAD(struct list_head *list) /** * 加入链表头部 */ list_add(struct list_head *_new, struct list_head *head) /** * 加入链表尾部 */ list_add_tail(struct list_head *_new, struct list_head *head) /** * 把指定节点从链表中删除 */ list_del(struct list_head *entry) /** * 把指定节点从链表中删除,并初始此节点 */ list_del_init(struct list_head *entry) /** * 获取当前节点元素 */ list_entry(ptr, type, field) /** * 获取后一个节点元素 */ list_first_entry(ptr, type, field) /** * 获取前一个节点元素 */ list_last_entry(ptr, type, field) /** * 向后遍历链表,遍历过程不能操作链表,p为节点元素结构体 */ list_for_each_entry(p, h, field) /** * 向前遍历链表,遍历过程不能操作链表,p为链表结构体 */ list_for_each_prev(p, h)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2018-12-28 搭建自己的MQTT服务器
2018-12-28 Linux编程实现蜂鸣器演奏康定情歌
2018-12-28 linux c MQTT客户端实现
2016-12-28 最详细的Log4j使用教程