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 head[];    /** 指向buf开始地址 */
};

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;
};

2. 存储结构

3. 函数

初始化/销毁

/**
 * 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)

写入read buffer

/*
 * ustream_reserve: allocate rx buffer space
 *      分配len大小的read buffer可用内存空间,与ustream_fill_read()配合使用
 *
 * len: int for how much space is needed (not guaranteed to be met)
 * maxlen: pointer to where the actual buffer size is going to be stored
 */
char *ustream_reserve(struct ustream *s, int len, int *maxlen)

/**
 * ustream_fill_read: mark rx buffer space as filled
 *      设置被ustream_reseve()分配read buffer后写入的数据大小,
 *      回调notify_read()接口,表示有数据可读
 */
void ustream_fill_read(struct ustream *s, int len)

读出read buffer,一般在notify_read()回调接口使用。

/*
 * ustream_get_read_buf: get a pointer to the next read buffer data
 *      获取新一次写入的内容,与ustream_consume()配置使用
 */
char *ustream_get_read_buf(struct ustream *s, int *buflen)

/**
 * ustream_consume: remove data from the head of the read buffer
 */
void ustream_consume(struct ustream *s, int len)

操作write buffer,尽最大能力调用write()回调用接口写入,如果超出能力将未写入的数据存储在write buffer中。

/*
 * ustream_write: add data to the write buffer
 */
int ustream_write(struct ustream *s, const char *buf, int len, bool more)
int ustream_printf(struct ustream *s, const char *format, ...)
int ustream_vprintf(struct ustream *s, const char *format, va_list arg)

把在write buffer 中的数据写入实际地方,调用write()回调接口和notify_write()回调接口。

一般在描述符的poll操作中调用,表示当描述符变为可写时立即把上一次写入的内容进行写入操作。

/*
 * ustream_write_pending: attempt to write more data from write buffers
 * returns true if all write buffers have been emptied.
 */
bool ustream_write_pending(struct ustream *s)
时间: 2024-12-31 12:30:07

libubox-ustream的相关文章

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组件(3)——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组件(2)——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-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 ----------------------------------------------------------------

安装OpenResty开发环境

OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极高的动态 Web 应用.Web 服务和动态网关(摘自官网).本文将会介绍如何在Centos7上,安装Nginx+Lua的开发环境,并运行一个"Hello World"示例. 一.环境安装 1.1 创建工作路径 我计划将Openresty安装到/usr/servers下,首先创建这个文件夹. [[email

Openwrt 初探

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